1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【42】pipexで使うシステムコール(プロセス制御)

Posted at

こんにちは。

42Tokyo本科生のなかじです。

今回は、前回投稿したpipexという課題で用いることが出来るシステムコールの中でもプロセス制御関連についてまとめてみました。

そもそもシステムコールとは何か?

システムコールとは、OSカーネルの機能や関数を呼び出すために使用する機能です。

例えば、C言語においてはmalloc() という動的メモリ確保を行うライブラリ関数は、その関数内においてsrbk() というシステムコールを呼び出すことでヒープ拡張が行われています。

execve()

使用目的

  • 現在のプロセスで新しいプログラムを実行
  • プロセスのテキスト、データ、スタック、ヒープを新しいプログラムで置き換え

使い方

int execve(const char *pathname, char *const argv[], char *const envp[]);
  • pathname: 実行するプログラムのパス
  • argv: コマンドライン引数の配列
  • envp: 環境変数の配列

使用例

pid_t pid = fork();
if (pid == 0) {  // 子プロセス
    char *const args[] = {"ls", "-l", NULL};
    char *const env[] = {
        "PATH=/bin:/usr/bin",
        "USER=username",
        NULL
    };
    
    if (execve("/bin/ls", args, env) == -1) {
        perror("execve failed");
        exit(1);
    }
} else {  // 親プロセス
    wait(NULL);  // 子プロセスの終了を待つ
}

戻り値

  • 成功: 返らない(新しいプログラムが実行される)
  • 失敗: -1 (errnoがセット)

特徴

  1. 保持される情報:
  • プロセスID(PID)
  • 親プロセスID(PPID)
  • プロセスグループID
  • オープンしているファイルディスクリプタ(O_CLOEXECフラグがないもの)

重要な点

  • 呼び出しが成功すると元のプログラムには戻らない
  • ファイルディスクリプタは継承される
  • argvとenvpはNULLで終端する必要がある
  • 実行権限が必要

exit()

使用目的

  • プロセスを終了する
  • 終了ステータスを親プロセスに返す
  • リソースの解放を行う

使い方

void exit(int status);
  • status: 終了ステータス(0-255)
    • 0: 正常終了
    • 非0: エラー終了

使用例

void cleanup(void) {
    printf("Cleaning up...\n");
}

int main(void) {
    atexit(cleanup);  // 終了時に実行する関数を登録
    
    if (some_error) {
        exit(1);  // エラー終了
    }
    
    // 処理成功
    exit(0);  // 正常終了
}

戻り値

  • なし

特徴

  1. 終了処理の順序:
  • atexit登録関数の実行(逆順)
  • 標準入出力のバッファをフラッシュ
  • 一時ファイルの削除
  • _exit()システムコールの呼び出し

重要な点

  • バッファリングされた出力は自動的にフラッシュされる
  • 子プロセスは親プロセスにステータスを返す
  • 親プロセスはwait()で終了ステータスを取得可能
  • atexit()で登録した関数は必ず実行される
  • リソースは自動的に解放される

fork()

使用目的

  • 新しいプロセス(子プロセス)を作成
  • 現在のプロセス(親プロセス)の複製を生成

使い方

pid_t fork(void);

使用例

pid_t pid = fork();

if (pid == -1) {
    // fork失敗
    perror("fork failed");
    exit(1);
} else if (pid == 0) {
    // 子プロセス
    printf("Child: PID = %d, Parent PID = %d\n", 
           getpid(), getppid());
} else {
    // 親プロセス
    printf("Parent: PID = %d, Child PID = %d\n", 
           getpid(), pid);
    wait(NULL);  // 子プロセスの終了を待つ
}

戻り値

  • 親プロセス: 子プロセスのPID
  • 子プロセス: 0
  • 失敗: -1 (errnoがセット)

特徴

  1. 複製される要素:
  • メモリ空間
  • ファイルディスクリプタ
  • 各種属性とフラグ

重要な点

  • 子プロセスは親プロセスの完全な複製
  • fork後は親子で別々の実行パスを取る
  • ファイルディスクリプタは共有される
  • メモリは実際の書き込み時にコピー(Copy-on-Write)

wait()

使用目的

  • 子プロセスの終了を待つ
  • 子プロセスの終了ステータスを取得
  • ゾンビプロセスの防止

使い方

pid_t wait(int *status);
pid_t waitpid(pid_t pid, int *status, int options);

使用例

pid_t pid = fork();

if (pid == 0) {
// 子プロセス
    exit(5);// 終了ステータス5で終了
} else {
// 親プロセス
    int status;
    pid_t child_pid = wait(&status);

    if (WIFEXITED(status)) {
// 正常終了の場合
        printf("Child %d exited with status %d\n",
               child_pid, WEXITSTATUS(status));
    }
}

終了ステータスのマクロ

WIFEXITED(status)// 正常終了したか
WEXITSTATUS(status)// exit()の引数値
WIFSIGNALED(status)// シグナルで終了したか
WTERMSIG(status)// 終了シグナル番号
  • status: 子プロセスの終了状態を格納する変数へのポインタ

戻り値

  • 成功: 終了した子プロセスのPID
  • 失敗: -1 (errnoがセット)

特徴

  • 子プロセスがない場合はエラー
  • 既に終了している子プロセスの情報も取得可能
  • ゾンビプロセス防止に重要
  • シグナルハンドラでの使用時は注意が必要

waitpid()

使用目的

  • 特定の子プロセスの終了を待つ
  • より柔軟な待ち合わせ制御
  • 非ブロッキング待ち合わせの実現

使い方

pid_t waitpid(pid_t pid, int *status, int options);
  • pid: 待つプロセスのPID
    • pid > 0: 指定したPIDのプロセス
    • pid == -1: 任意の子プロセス(waitと同じ)
    • pid == 0: 同じプロセスグループの子プロセス
    • pid < -1: プロセスグループID = |pid|の子プロセス
  • status: 終了状態を格納する変数
  • options: 動作オプション
    • WNOHANG: ノンブロッキング
    • WUNTRACED: 停止子プロセスの状態も報告
    • WCONTINUED: 再開子プロセスの状態も報告

戻り値

  • 成功: 終了/停止した子プロセスのPID
  • 子プロセスがまだ終了していない(WNOHANG時): 0
  • 失敗: -1 (errnoがセット)

特徴

  1. wait()より柔軟な制御が可能
  2. ノンブロッキング動作が可能
  3. 特定のプロセスやグループを指定可能
  4. 停止/再開の監視も可能
  5. 複数の子プロセスの管理に適している
1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?