此问题在此处已有答案:
Zombie processes(5个答案)
28天前关闭。
我有一个多进程程序。简单说明一下这个问题,子进程只会被阻塞,主进程判断子进程是否还存在,如果存在则父进程杀死子进程。
我的代码如下:
#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/wait.h>
#include <stdlib.h>
#include <time.h>
#include <errno.h>
#include <sys/socket.h>
#include <string.h>
#define TIME_OUT 3
int get_current_time()
{
struct timespec t;
clock_gettime(CLOCK_REALTIME, &t);
return t.tv_sec;
}
void child_process_exec()
{
int fd = open("./myfifo", O_WRONLY); // myfifo is a named pipe, here will be blocked.
sleep(10);
}
void parent_process_exec(pid_t workProcessId)
{
int status;
int childRes;
int lastHeartBeatTime = get_current_time();
while(1) {
sleep(1);
if (get_current_time() - lastHeartBeatTime> TIME_OUT) {
childRes = waitpid(workProcessId, &status, WNOHANG);
if(childRes == 0) {
printf("kill process\n");
printf("kill get %d\n", kill(workProcessId, SIGTERM));
}
workProcessId = fork();
if(workProcessId > 0) {
lastHeartBeatTime = get_current_time();
} else {
printf("start up child process again\n");
child_process_exec();
return;
}
}
}
}
int main()
{
pid_t workProcessId = fork();
if (workProcessId > 0) {
parent_process_exec(workProcessId);
} else {
child_process_exec();
}
return 0;
}
字符串
但是我用ps
得到的子进程是<defunct>
在终端。为什么kill()后子进程变成僵尸了呢?如何干净地杀死子进程?
2条答案
按热度按时间h6my8fg21#
1.在t+3s时,调用
waitpid(..., WNOHANG)
,它立即返回,而没有获得子对象,这一点在childRes == 0
中很明显。杀死第一个子节点,然后用第二个子节点的pid覆盖workProcessId
。冲洗并重复。这意味着waitpid()
在子进程终止后永远不会被调用,而在t=T
中,您最终会得到T/3
僵尸子进程。最简单的修复方法是将WNOHANG
更改为0,以便父块等待子块。您可以通过使用wait()
来阻止等待任何孩子来获得类似的效果。或者,维护一个pid_t数组来保存每个还没有被收割的孩子。然后用
waithpid(..., WNOHANG)
循环该数组。1.您可能希望修复
parent_process_exec()
中的逻辑,使其不会无条件地派生一个新的子进程。1.在Linux上,我必须为
kill()
包含signal.h
。1.将
int workProcessId
更改为pid_t workProcessId
。open()
的第二个参数是一个int
,而不是一个字符串,所以你想使用O_WRONLY
而不是"O_WRONLY"
。始终检查返回值。jk9hmnmh2#
根据@Useless的this,我在kill子进程后添加
wait()
,现在父进程收割子进程。像这样字符串
我知道一个僵尸进程只是一个pid,它是无害的,但我认为应该有一种方法来杀死子进程。但是在父进程杀死它的子进程后,还有一个僵尸进程,这真的让我很困惑。