【发布时间】:2017-08-02 07:20:28
【问题描述】:
我尝试在以下代码中同时启动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);
}
我在sig_handler 中捕捉到SIGCHLD 信号,结果不同:有时所有进程都返回OK;有时 1 到 4 个进程会变成僵尸。
[vinllen@my-host]$ ./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
[vinllen@my-host ~]$ 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 是解决这个问题的两种有效方法。但是,如何在这段代码中解决仍然调用wait。
【问题讨论】:
-
信号处理程序中的
cout可能是罪魁祸首。你应该只在信号处理程序中调用async-signal-safe functions。一般来说,尽量缩短信号处理程序,并通过volatile sig_atomic_t变量与主代码进行通信。
标签: c++ linux fork zombie-process waitpid