c - fork() - 如何让最后一个子进程杀死父进程/原始进程?

标签 c signals fork kill-process

我想让 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/

相关文章:

c++ - 为什么连接的信号有参数但插槽没有参数?

c - 从 SIGCHLD 返回的信号似乎是错误的

perl - Perl 如何在并行处理中共享全局变量?

perl - Perl fork 服务器测试程序-accept()失败

c++ - fork() 和 exec() 两个子进程

在 Linux coreutils 包中编译特定的源文件

c - Haskell - 相当于 for 循环?

c - 如何将 txt 文件中的数据加载到我的 C 程序中的变量中?

python - 如何对 "signal"感兴趣的子进程(无信号)?

c - 编译器语法中if then else的翻译