c语言 - 使用 fork() 创建"background running"子项,并用信号杀死每个子项



我需要从同一个父级创建n个子级,并让它们运行,而父级无限地要求将信号发送给某个子级。我让父级创建了这 n个子项,但它们完成了执行,所以我让它们进入 while(1) 循环。问题是,当我试图杀死任何孩子时,它变成了一个僵尸进程,而不是真正终止其执行。我猜这是因为父母仍在等待孩子终止执行,并且他们不发送退出状态。所以。。。首先,我真的需要让孩子进入一个无限的while循环,让他们在父母请求信号时运行吗?如果我这样做,如何避免这种"永不终止执行"的问题?我需要找到一种方法让孩子们退出那个 while 循环并发送实际的"完成执行"信号,因为我认为我不能使用wait()因为孩子们从未真正完成运行,他们只是被父母终止。

谢谢。 PS:在Linux中运行。这是我的代码

int main(){
int i;
pid_t parent = getpid();
pid_t pid[4];
printf("parent with pid %dn", parent);
for(i = 0; i < 5; i++){
pid[i] = fork();
if(pid[i] < 0){
perror("Error in fork.");
exit(1);
} else if(pid[i] == 0 && getppid() == padre) {
printf("Number: %d   pid %d, parent: %dn", i, getpid(), getppid());
while(1);
}
}
if(getpid() == padre){
while(1){
printf("Enter pid and signal:n");
int x, y;
scanf("%d", &x); // pid
scanf("%d", &y); // signal
printf("you did: kill(%d, %d)n", x, y);
kill(x, y);
}
}
return 0;
}

编辑:实现答案的最终代码:https://github.com/sebasura/sistope

问题是,当我试图杀死任何孩子时,它会变成一个僵尸进程,而不是真正终止其执行。

嗯,是也不是。 成为僵尸通常是在进程终止时发生的情况,直到该进程被其父进程收集为止。 僵尸在进程表中占用一点空间,但它没有运行,因此不消耗 CPU。

我猜这是因为父母仍在等待孩子终止执行,并且他们不发送退出状态。

不,这是因为kill()只是发送了一个信号。 您需要使用wait()函数之一(也许是waitpid())来实际收集已终止的孩子。

所以。。。首先,我真的需要让孩子进入一个无限的while循环,让他们在父母请求信号时运行吗?

不。 子项可以使用sigwait()或其变体之一来等待来自指定集合的信号,或者pause()暂停执行,等待收到终止进程或触发信号处理程序函数的任何信号。 但是请注意,默认情况下,有些信号不会执行这些操作,因此sigwait()可能是更好的选择。

如果我这样做,如何避免这种"永不终止执行"的问题?

孩子必须因接收到信号而终止。 这已经在你身上发生了,因为孩子们正在变成僵尸。 但是,对于您当前的代码,它可能取决于您发送的信号,因为有些信号的默认处理不会终止该过程。

谢谢大家,我做到了。 我用pause()而不是while(1).

杀完之后,我用了这个:

int state;
waitpid(pid, &state, 0);

这是家庭作业的一部分,所以我会在截止日期后上传代码,这样他们就不会因为分享它或其他东西而惩罚我。

再次感谢。 编辑: 这是最终的代码 https://github.com/sebasura/sistope

最新更新