避免在C++中产生僵尸进程
Avoiding the production of zombie processes in C++
非常奇怪的bug,也许有人会看到我缺少的东西。
我有一个C++程序,它派生出一个bash shell,然后将命令传递给它
命令将定期包含无意义的内容,bash进程将挂起。我使用semtimedwait检测到这一点,然后运行一个类似的小函数:
if (kill(*bash_pid, SIGKILL)) {
cerr << "Error sending SIGKILL to the bash process!" << endl;
exit(1);
} else {
// collect exit status
long counter = 0;
do {
pid = waitpid(*bash_pid, &status, WNOHANG);
if (pid == 0) { // status not available yet
sleep(1);
}
if(counter++ > 5){
cerr << "ERROR: Bash child process ignored SIGKILL >5 sec!" << endl;
}
} while (pid != *bash_pid && pid != -1);
if(pid == -1){
cerr << "Failed to clean up zombie bash process!" << endl;
exit(1);
}
// re-initialized bash process
*bash_pid = init_bash();
}
假设我正确地理解了waitpid的工作原理,那么应该首先将SIGKILL发送到shell,然后本质上坐在一个spinlock中,试图获得结果过程。最终,它成功了,然后用init_bash()启动了一个新的bash进程。
至少,这是应该发生的事情。相反,子进程的退出状态从未被收集,并且它继续作为僵尸进程存在。尽管如此,父确实退出循环并设法重新启动bash进程,然后继续正常执行。最终生成了太多僵尸,系统中的pid也用完了。
另外:
- Fork在程序中的init_bash内的一个位置被调用
- 检查可防止init_bash被调用,除非在程序启动时和调用上述函数后调用一次
想法?
我读到的文章表明,僵尸进程的原因是子进程退出,而父进程从不收集子进程的退出。
本文提供了几种从命令行杀死僵尸进程的方法。一种技术是使用SIGKILL之外的其他信号,例如SIGTERM。
本文给出的答案表明不应该使用SIGKILL。
其中一种技术是杀死父进程,从而也杀死其子进程,包括任何僵尸。作者指出,在操作系统重新启动之前,似乎有一些子进程仍然是僵尸。
您没有提及用于将命令传达给子进程的机制。然而,一种选择可能是通过断开子进程与其父进程的连接来释放子进程,类似于终端进程的子进程与终端会话的连接。这样,孩子将成为自己的过程,如果出现问题,可能会退出而不会变成僵尸。
相关文章:
- 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++)中防止僵尸进程