同时分叉 100 个进程,有时有些进程会变成僵尸
fork 100 processes at same time and sometimes some processes become zombie
我尝试在以下代码中同时启动 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("waitn");
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
。
信号不排队。 如果在 SIGCHLD 处于挂起状态时引发(可能是当您的代码处于write
系统调用中时(,程序将只收到一条通知。
处理此问题的正确方法是在处理程序中循环,直到收获所有完成的子项:
void sig_handler(int signo) {
pid_t pid;
int stat;
while ((pid = waitpid(-1, &stat, WNOHANG) > 0)
if (WIFEXITED(stat))
{
// Don't actually do this: you should
// avoid buffered I/O in signal handlers.
std::cout << "count:" << ++cnt
<< ", pid:" << pid
<< " signal:" << signo
<< std::endl;
}
}
如注释中所述,您应该坚持使用信号处理程序中记录的异步信号安全函数。 缓冲 I/O(包括使用std::cout
(可能存在风险,因为信号处理程序可以在操纵其内部结构时被调用。 避免问题的最佳方法是限制自己使用volatile sig_atomic_t
变量与主代码进行通信。
相关文章:
- boost::进程间消息队列引发错误
- 在进程中对同一管道进行读取和写入时C++管道出现问题
- 是否可以通过C++扩展强制多个python进程共享同一内存
- IPC使用多个管道和分支进程来运行Python程序
- 异常属于C++中的线程还是进程
- WMI检测进程创建事件-c++
- c++多进程编写一个唯一的文件
- 如何在C++中将函数发送到另一个进程
- 在Qt Creator中,如何在连接到正在运行的进程后查看控制台输出
- 终止 QProcess 不会终止子进程
- 将返回值从 exe 传递到 bat,并将其传递给 C# 中的进程
- COM :是否可以查看是否存在对我的某个 COM 对象的进程外引用?我可以释放它吗?
- Windows 进程间同步类似事件?
- 同时分叉 100 个进程,有时有些进程会变成僵尸
- posix_spawn创建一个僵尸进程并返回成功
- Linux fork - execl,执行的进程变成僵尸
- 避免在C++中产生僵尸进程
- 从C++通过RPC启动新线程会导致进程陷入僵尸状态
- pthread_join失败是否会导致子进程成为僵尸
- 在自实现的linux shell (c++)中防止僵尸进程