C 言語での wait 関数
この記事では、C 言語で wait
関数を利用する方法について複数の方法を示します。
関数 wait
を使って C 言語の子プロセスの状態変化を待つ
関数 wait
は POSIX に準拠したシステムコールのラッパーであり、<sys/wait.h>
ヘッダファイルで定義されています。この関数は、子プロセスのプログラムの状態変化を待ち、対応する情報を取得するために用いられます。通常、wait
は新しい子プロセスを生成する fork
システムコールの後に呼ばれます。wait
コールは、呼び出したプログラムの子プロセスの 1つが終了するまで、呼び出したプログラムを一時停止します。
ユーザは、呼び出し元のプロセスと子プロセスのパスが異なる 2つのパスになるようにコードを構成しなければならません。これは通常、fork
関数呼び出しの戻り値を評価する if...else
文で実現されています。fork
は親プロセスでは子プロセス ID を正の整数で返し、子プロセスでは 0 を返すことに注意してください。fork
は呼び出しが失敗した場合に -1 を返します。
#include <stdio.h>
#include <stdlib.h>
#include <sys/wait.h>
#include <unistd.h>
int main() {
pid_t c_pid = fork();
if (c_pid == -1) {
perror("fork");
exit(EXIT_FAILURE);
}
if (c_pid == 0) {
printf("printed from child process %d", getpid());
exit(EXIT_SUCCESS);
} else {
printf("printed from parent process %d\n", getpid());
wait(NULL);
}
exit(EXIT_SUCCESS);
}
C 言語で特定の子プロセスの状態変化を待つには waitpid
関数を用いる
waitpid
は wait
関数を少し改良したもので、特定の子プロセスを待つ機能を提供し、戻り値のトリガ動作を変更することができます。waitpid
は、子プロセスが終了した場合に加えて、子プロセスが停止した場合や継続した場合にも返すことができます。
以下の例では、子プロセスから pause
関数を呼び出し、シグナルを受信するまでスリープ状態にします。一方、親プロセスは waitpid
関数を呼び出し、子プロセスが戻るまで実行を中断します。また、マクロ WIFEXITED
と WIFSIGNALED
を用いて、子プロセスが正常終了したかシグナルによって終了したかを確認し、対応するステータスメッセージをコンソールに出力します。
#include <stdio.h>
#include <stdlib.h>
#include <sys/wait.h>
#include <unistd.h>
int main() {
pid_t child_pid, wtr;
int wstatus;
child_pid = fork();
if (child_pid == -1) {
perror("fork");
exit(EXIT_FAILURE);
}
if (child_pid == 0) {
printf("Child PID is %d\n", getpid());
pause();
_exit(EXIT_FAILURE);
} else {
wtr = waitpid(child_pid, &wstatus, WUNTRACED | WCONTINUED);
if (wtr == -1) {
perror("waitpid");
exit(EXIT_FAILURE);
}
if (WIFEXITED(wstatus)) {
printf("exited, status=%d\n", WEXITSTATUS(wstatus));
} else if (WIFSIGNALED(wstatus)) {
printf("killed by signal %d\n", WTERMSIG(wstatus));
}
}
exit(EXIT_SUCCESS);
}