になる私は、次のコードで同時に100個のプロセスを起動しよう:私はsig_handler
でSIGCHLD
信号をキャッチ同時にフォーク100個のプロセスを、時にはいくつかのプロセスがゾンビ
int cnt = 0;
void sig_handler(int signo) {
pid_t pid;
int stat;
pid = wait(&stat);
cout << "cnt:" << ++cnt << ", pid:" << pid << " signal:" << signo << endl;
}
int main() {
signal(SIGCHLD, sig_handler);
for (int i = 0; i < 100; ++i) {
if (fork() == 0) {
sleep(1);
exit(0);
}
}
printf("wait\n");
while (1);
}
、結果が異なります。場合によってはすべてのプロセスがOKを返します。場合によっては1〜4プロセスがゾンビになることがあります。
[[email protected]]$ ./a.out
wait
cnt:1, pid:4383 signal:17
cnt:2, pid:4384 signal:17
cnt:3, pid:4385 signal:17
cnt:4, pid:4386 signal:17
cnt:5, pid:4387 signal:17
…
cnt:94, pid:4476 signal:17
cnt:95, pid:4477 signal:17
cnt:96, pid:4478 signal:17
cnt:97, pid:4479 signal:17
cnt:98, pid:4480 signal:17
[[email protected] ~]$ ps aux | grep a.out
Vinllen 4382 96.2 0.0 13896 1084 pts/8 R+ 15:14 0:03 ./a.out
Vinllen 4481 0.0 0.0 0 0 pts/8 Z+ 15:14 0:00 [a.out] <defunct>
Vinllen 4482 0.0 0.0 0 0 pts/8 Z+ 15:14 0:00 [a.out] <defunct>
Vinllen 4493 0.0 0.0 105300 864 pts/9 S+ 15:14 0:00 grep a.out
私は、複数のプロセスが同時に終了して何かをトリガーする理由を推測します。誰も私に詳細な理由を教えて、この問題を解決する方法を教えてください。
私の理解では、この問題を解決するには、二重フォークとSIGCHLDを無視する2つの効果的な方法があります。しかし、このコードで解決するにはまだwait
を呼び出す。
シグナルハンドラの 'cout'が原因である可能性があります。シグナルハンドラでは、[* async-signal-safe * functions](http://man7.org/linux/man-pages/man7/signal-safety.7.html)のみを呼び出すことになっています。一般に、シグナルハンドラはできるだけ短くして、 'volatile sig_atomic_t'変数を通してメインコードと通信してください。 –