waitpid()関数のLinuxにおける使用方法
Linuxには、waitpid()関数があり、指定された子プロセスの状態変化を待つことができます。プロトタイプは次のとおりです。
#include <sys/types.h>
#include <sys/wait.h>
pid_t waitpid(pid_t pid, int *status, int options);
その中で、pidパラメーターで待機する子プロセスIDを指定することができ、以下のような値をとることができます。
- pidが0より大きい場合は、指定されたプロセスIDを持つ子プロセスを待つことを意味します。
- pidが0なら,呼び出しプロセスと同じプロセスグループに属する任意の子プロセスを待つことを示します.
- pidが -1 の場合は、wait() 関数と同様に、どの子供プロセスでも待機します。
- pidが-1よりも小さければ、その絶対値のpidを持つ任意の子プロセスのプロセスグループIDを待つことを示す。
status引数はNULLにすることもでき、子プロセスの終了ステータスを格納するために使用する整数ポインタです。
オプションパラメータは待機の動作を設定するために使用され、以下の値の組み合わせとなる
- 続行:一時停止中のサブプロセスが実行を再開するのを待つ;
- WNOHANG:子プロセスの状態に変化がなければ、ブロックせずに即座に返る。
- トレースアンダー:一時停止状態または終了済の子プロセスを待つ
- WSTOPPED:一時停止した子プロセスを待ちます。
waitpid()関数の戻り値は子プロセスのプロセスID、エラーの場合は-1を返します。
サンプルコードは下記の通りです
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
int main() {
pid_t pid;
int status;
pid = fork();
if (pid < 0) {
perror("fork");
exit(1);
} else if (pid == 0) {
// 子进程
printf("Child process: PID=%d\n", getpid());
sleep(5);
exit(0);
} else {
// 父进程
printf("Parent process: PID=%d, Child PID=%d\n", getpid(), pid);
waitpid(pid, &status, 0);
if (WIFEXITED(status)) {
printf("Child process exited with status %d\n", WEXITSTATUS(status));
} else if (WIFSIGNALED(status)) {
printf("Child process terminated by signal %d\n", WTERMSIG(status));
} else if (WIFSTOPPED(status)) {
printf("Child process stopped by signal %d\n", WSTOPSIG(status));
}
}
return 0;
}
上のサンプルコードでは、親プロセスがfork()関数で子プロセスを作成して、子プロセスの状態変化をwaitpid()関数で待っています。子プロセスでは、5秒間スリープしてから終了します。親プロセスはwaitpid()関数が返ってきたら、子プロセスの終了ステータスに応じてメッセージを出力します。
waitpid() 関数の status 引数はポインタであって、子プロセスの終了ステータスを格納するために使われます。WIFEXITED、WEXITSTATUS、WIFSIGNALED、WTERMSIG、WIFSTOPPED、WSTOPSIG といったマクロ関数によって子プロセスが正常終了したのか、異常終了したのか、あるいは停止状態なのかを調べられます。