7

私が子forkプロセスであり、親が呼び出す前に子プロセスが終了した場合waitpid、によって設定された終了ステータス情報はwaitpidまだ有効ですか?もしそうなら、それはいつ無効になりますか。つまり、waitpid子pidを呼び出して、任意の時間が経過した後も有効な終了ステータス情報を取得し続けることができるようにするにはどうすればよいですか。また、「クリーンアップ」するにはどうすればよいですか(終了に関心がなくなったことをOSに通知します)。終了した子プロセスのステータス情報)?

次のコードで遊んでいたところ、終了ステータス情報は子が終了してから少なくとも数秒間は有効であるように見えますが、OSに通知する期間や方法がわかりません。waitpid再度呼び出す:

#include <assert.h>
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/wait.h>

int main()
{
    pid_t pid = fork();

    if (pid < 0) {
        fprintf(stderr, "Failed to fork\n");
        return EXIT_FAILURE;
    }
    else if (pid == 0) { // code for child process
        _exit(17);
    }
    else { // code for parent
        sleep(3);

        int status;
        waitpid(pid, &status, 0);
        waitpid(pid, &status, 0); // call `waitpid` again just to see if the first call had an effect
        assert(WIFEXITED(status));
        assert(WEXITSTATUS(status) == 17);
    }

    return EXIT_SUCCESS;
}
4

3 に答える 3

13

はい、waitpid子供が出た後に動作します。waitpidOSは、親が呼び出すまで(または別のwaitファミリ関数)、または親が終了するまで(その時点でステータスがプロセスによって収集されるまで)、プロセステーブル(終了ステータスを含む)に子プロセスのエントリを保持しますinit。これが「ゾンビ」プロセスです。によって終了したプロセスは、まさにこの目的のためにプロセステーブルに常駐しています。

テーブル内のプロセスのエントリは、への最初の呼び出し後に消えるはずですwaitpid。あなたの例でwaitpid2回呼び出すことができるように見える理由は、単に引数が存在しなくなった場合に引数waitpidを変更しないためだと思います。したがって、最初の呼び出しは機能して入力されている必要があり、2番目の呼び出しはエラーコードを返し、変更されていない必要があります。これは、呼び出しの戻り値を調べたり、2つの異なる変数を使用したりすることで確認できます。statuspidstatusstatuswaitpidstatus

于 2010-05-19T13:02:25.730 に答える
3

OSは、その親(元の親プロセスが以前に終了した場合)がシステムコールでその終了ステータスを収集するまで、終了したプロセスをゾンビ状態に保ちます。したがって、答えは次のとおりです。プロセスの終了ステータスが無効になることはありませんinitwait(2)

于 2010-05-19T13:02:52.040 に答える
2

はい。

マニュアルページから:

終了するが待たされていない子は「ゾンビ」になります。カーネルは、親が子に関する情報を取得するために後で待機を実行できるようにするために、ゾンビプロセスに関する最小限の情報セット(PID、終了ステータス、リソース使用情報)を維持します。

于 2010-05-19T13:06:27.643 に答える