子プロセスが親プロセスで終了するUNIXバリアントはありますか?

子プロセスが親プロセスで終了するUNIXバリアントはありますか?

私はしばらくの間Linuxカーネルの振る舞いを研究してきました、そして常に明確でした。

プロセスが終了すると、すべての子プロセスはinit最終的に終了するまでそのプロセス(PID 1)に返されます。

ところで、最近私よりカーネル経験の多い誰かが私にこう言った。

プロセスが終了すると、その子プロセスもすべて終了します(実行ファイルを使用してをNOHUP返さない限りinit)。

私はこれを信じていませんが、それを確実にするために簡単なプログラムを書いています。私はsleepテストのために時間()が完全にプロセススケジューリングに依存しているので依存してはいけませんが、この単純なケースではそれだけで十分だと思います。

int main(void){
    printf("Father process spawned (%d).\n", getpid());
    sleep(5);

    if(fork() == 0){
        printf("Child process spawned (%d => %d).\n", getppid(), getpid());
        sleep(15);
        printf("Child process exiting (%d => %d).\n", getppid(), getpid());
        exit(0);
    }

    sleep(5);
    printf(stdout, "Father process exiting (%d).\n", getpid());
    return EXIT_SUCCESS;
}

ps以下は、各printf会話の関連結果を含むプログラムの出力です。

$ ./test &
Father process spawned (435).

$ ps -ef | grep test
myuser    435    392   tty1    ./test

Child process spawned (435 => 436).

$ ps -ef | grep test
myuser    435    392   tty1    ./test
myuser    436    435   tty1    ./test

Father process exiting (435).

$ ps -ef | grep test
myuser    436    1     tty1    ./test

Child process exiting (436).

今見ているように、これが私が期待したものです。孤児プロセス(436)はinit終了するまで(1)に返されます。

しかし、この動作をデフォルトで適用しないUNIXベースのシステムはありますか?プロセスが終了するとすぐにすべての子プロセスが終了するシステムはありますか?

ベストアンサー1

プロセスが終了すると、すべての子プロセスも終了します(NOHUPを使用してinitに戻らない限り)。

これは間違っています。本当に間違っています。そう言う人は、間違っているか、特定の状況を一般的な状況と混同することです。

プロセスが死ぬ方法は2つあります。間接的にその結果、彼の子供たちは死にました。ターミナルが閉じたときに何が起こるかに関連しています。 SIGHUP信号は、端末が消えたときに発生します。 (歴史的には、モデムの切断によってシリアル回線が切断されたため、現在は通常、ユーザーが端末エミュレータウィンドウを閉じているためです。)送信された到着制御プロセスこの端末で実行 - 通常、初期シェルはこの端末で開始されます。シェルは通常終了してそれに反応します。対話型使用のためのシェルは、シャットダウン前に開始する各ジョブにHUPを送信します。

シェルでジョブを開始すると、ジョブはシグナルをnohup無視し、端末が消えたときに終了するように求められないため、HUPシグナルの2番目のソースが破壊されます。シェルからジョブへのHUP信号の伝播を中断する別の方法は、disown可能であればシェルの組み込み機能を使用することです(タスクはシェルのジョブリストから削除されます)。が含まれます。独自に子プロセスを開始し、すぐに終了します。シェルは孫プロセスについて知らない。

同様に、ターミナルで開始されたタスクは、親プロセス(シェル)が終了するため終了するのではなく、そのタスクを終了するように指示されたときに、その親プロセスがそのタスクを終了することを決定するために終了します。ターミナルの初期シェルは、親プロセスが死ぬからではなく、ターミナルが消えるために死にます(ターミナルはシェル親プロセスのターミナルエミュレータによって提供されるため、これは偶然かもしれません)。

おすすめ記事