5

プログラムをデーモンとして実行しています。

親プロセスは子プロセスだけを待ちます。子プロセスが予期せず停止した場合は、分岐して再度待ちます。

for (; 1;) {
  if (fork() == 0) break;
  int sig = 0;
  for (; 1; usleep(10000)) {
    pid_t wpid = waitpid(g->pid[1], &sig, WNOHANG);
    if (wpid > 0) break;
    if (wpid < 0) print("wait error: %s\n", strerror(errno));
  }
}

ただし、子プロセスが -9 シグナルで強制終了されると、子プロセスはゾンビ プロセスになります。

waitpid子プロセスの pid をすぐに返す必要があります。
しかしwaitpid、約90秒後にpid番号を取得し、

cube     28139  0.0  0.0  70576   900 ?        Ss   04:24   0:07 ./daemon -d
cube     28140  9.3  0.0      0     0 ?        Zl   04:24 106:19 [daemon] <defunct>

父の軌跡はこちら

父は引っかからず、常にwait4が呼び出されました。

strace -p 28139
Process 28139 attached - interrupt to quit
restart_syscall(<... resuming interrupted call ...>) = 0
wait4(28140, 0x7fff08a2681c, WNOHANG, NULL) = 0
nanosleep({0, 10000000}, NULL)          = 0
wait4(28140, 0x7fff08a2681c, WNOHANG, NULL) = 0

約 90 秒後、父は SIGCHILD を受け取り、wait4 は死んだ子供の pid を返しました。

--- SIGCHLD (Child exited) @ 0 (0) ---
restart_syscall(<... resuming interrupted call ...>) = 0
wait4(28140, [{WIFSIGNALED(s) && WTERMSIG(s) == SIGKILL}], WNOHANG, NULL) = 28140

子プロセスがすぐに終了しないのはなぜですか? それどころか、思わずゾンビ化。

4

3 に答える 3

3

lsofによる詳細なトレース中に、いくつかのfdリークがあったことが最終的にわかりました。

fd リークが修正された後、問題はなくなりました。

于 2014-04-30T15:45:48.947 に答える
1

そのプロセスが利用できないという理由だけで、waitpidが子pidをすぐに返していないように見えます。

waitpid()さらに、オプションで指定するため、実際にコードでこれを実行する必要があるように見えますNOHANG。これにより、ブロックが防止され、子 pid が使用できない場合に親が先に進むことが基本的に許可されます。

たぶん、あなたが予期していなかったものを使用しているプロセスですか?そのアクティビティを追跡して、ボトルネックを見つけられるかどうかを確認できますか?

これはあなたを助けるかもしれない非常に便利なリンクです: http://infohost.nmt.edu/~eweiss/222_book/222_book/0201433079/ch08lev1sec6.html

于 2014-04-29T21:13:54.897 に答える
1

あなたは単に使用することができます

  for (;;) {
    pid_t wpid = waitpid(-1, &sig, 0);
    if (wpid > 0) break;
    if (wpid < 0) print("wait error: %s\n", strerror(errno));
  }

しばらくスリープしてからやり直してください。

于 2014-03-29T18:20:22.457 に答える