本を読んでいますUnix環境の高度なプログラミング。この機能をテストするテストプログラムがありますfork
。私のUbuntuではうまくいきます。しかし、私を混乱させるのは、サブプロセスが終了した後にコマンドを表示するプロンプトがない理由です。元のプログラムは以下の通りです。
#include <stdio.h>
#include <unistd.h>
#include <sys/wait.h>
int main()
{
pid_t pid;
if ((pid = fork()) < 0)
{
printf("fork error.\n");
return 1;
}
else if (pid == 0)
{
if ((pid = fork()) < 0)
{
printf("fork error.\n");
return 1;
}
else if (pid > 0)
{
printf("first child %d exit.\n", getpid());
exit(0);
}
sleep(2);
printf("second child %d has parent pid = %d.\n",getpid(), getppid());
exit(0);
}
printf("waitid %d.\n", pid);
if (waitpid(pid, NULL, 0) != pid)
{
printf("waitid error.\n");
return 1;
}
printf("process %d will exit..\n", getpid());
exit(0);
}
だから私は走る
jerryli@ubuntu:~/project/unix$ ./p183.o
waitid 2256
first child 2256 exit.
process 2255 will exit..
jerryli@ubuntu:~/project/unix$ second child 2257 has parent pid = 1.
上記の行が表示された後は、何も続くことはありません。見せてほしい
jerryli@ubuntu:~/project/unix$
上記の指標を取得するには、を入力する必要がありますEnter。
理由がわかりますか? 2番目の子プロセスの親プロセスがシステム初期化プロセスになったためですか?
答え1
fork
バックグラウンドでプロセスを開始します。フォアグラウンドプロセス(呼び出しプロセスfork
)が終了すると、コールシェルに通知され、新しいプロンプトが表示されます。シェルは元のフォアグラウンドプロセスの親であり、分岐プロセスの親ではありません。
元のプロセスと分岐プロセスの実行順序は固定されていませんが、2秒の遅延によって関連する偏差が発生する可能性はほとんどありません。テストでは、タイムラインは次のようになります。
fork
元のプロセスの最初の子プロセスです。fork
最初の子供の2番目の子供。- 元のプロセスは
waitid
トレースを印刷し、waitpid
最初の子プロセスを待つために呼び出しを開始します。 - 最初の子プロセスは
exit
トレースを印刷してから終了します。 - 元のプロセスに子プロセスが終了したことを通知し、その
waitpid
呼び出しが返されます。 - 元のプロセスは
will exit
トレースを印刷します。 - シェルは元のプロセスが終了したことを知らせ、プロンプトを印刷します。
- 2秒以内に
sleep
2番目の子の呼び出しが完了し、2番目の子がそのトレースをhas parent
印刷します。
シェルは終了プロセスの親プロセスではないため、最後のイベントに関する通知は受け取りません。それにもかかわらず、すでに新しいコマンドを入力するのを待っているプロンプトが表示されています。何もする理由はありません(コマンドを入力すると邪魔になる可能性があります)。
答え2
@Gillesの答えに従って、@jerryが要求したものと同様のものを実装する予定です。 1.フォークする前に端末PIDを保存します。 2. 各印刷セットの後、SIGINT を送信して端末を「プッシュ」してプロンプトを表示します。
とても汚いですが、作業を完了したようです。