我想让 N 个 child (由 fork 生成)中的最后一个 child 杀死他的父亲。
我尝试过:
in the fork function
signal(SIGINT, processKilled);
int car_finished = 0;
for (int car = 0; car < CAR; car++) {
int pid = fork();
...
}
in the son
car_finished++;
if (car_finished == CAR-1){
kill(getppid(), SIGKILL);
}
exit(EXIT_SUCCESS);
但最后一个 child 不会杀死父亲......
我该怎么做?我不知道。
最佳答案
Graeme Cole已正确诊断您的问题在 comment :
- 每个子进程都有自己的
car_finished
副本,因此任何子进程中的计数只会达到1
,因此如果有多个子进程,信号永远不会已发送。
如何解决?
您可以使用共享内存并将 car_finished
放入共享内存中。但是,您必须在进程之间同步对共享内存的访问,因此这很快就会变得难以处理(假设在提到共享内存时它并不被认为是难以处理的)。
可以使用一个文件来包含子项的计数。子进程将在文件上使用(建议)锁定来防止并发访问,并且每个子进程都会在退出之前递减计数,而将计数减至零的子进程将删除该文件并向父进程发送信号。这是相当可靠的,但不是那么快(但它可能足够快)。如果子进程在没有减少计数的情况下退出(例如,因为内存故障而崩溃,或者发送了 SIGKILL),则会出现主要问题。那么计数永远不会为零,因此父级永远不会收到信号。
如果父进程只是等待子进程死亡,它应该在 wait()
循环中运行:
int corpse;
int status;
while ((corpse = wait(&status)) > 0)
{
/* …optionally… */
printf("%d: PID %d exited with status 0x.4X\n", (int)getpid(), corpse, status);
}
exit(EXIT_SUCCESS);
如果父进程正在做一些处理,子进程不应该发送SIGKILL;它让 parent 没有时间清理。每个子进程都可以向父进程发送 SIGUSR1 信号,父进程的信号处理程序可以计算收到的信号数量,并在收到所有信号后退出。完整演示起来比较麻烦,但使用 sigaction()
来设置信号处理程序。
有时,父级可以创建一个管道,关闭写入端,并尝试从中读取。 children 会在管道启动时关闭管道的读取端(代码卫生——这可以省略)。当子进程完成后,它会退出,显式或隐式关闭管道的写入端。当最后一个子进程退出时,父进程将从 read()
返回“零字节读取”,并且可以关闭管道(或只是终止)。
最后这些解决方案依赖于父进程的合作。这通常是一个安全的赌注(除非家庭功能失调,否则 parent 会尽可能地帮助他们的 child )。
关于c - fork() - 如何让最后一个子进程杀死父进程/原始进程?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59336644/