【问题标题】:terminating parent and child process on Ctrl-C在 Ctrl-C 上终止父子进程
【发布时间】:2026-01-15 06:55:02
【问题描述】:

我正在编写一个 C 程序,其中父进程分叉 n 个子进程。子进程一旦创建就会调用 SIGSTOP 以允许创建其他子进程。创建所有 n 个子进程后的父进程向所有子进程发送 SIGCONT 信号。

所有子进程执行一个无限循环并使用信号量共享一个公共资源。现在我希望每当用户按下 ctrl-c 时,父进程和所有子进程都会一起终止。但是,在终止子进程之前,应该在文件中更新每个子进程使用资源的次数。

例如:

Process 1 - 5 times
Process 2 - 3 times

等等。

在此实施中需要帮助...

【问题讨论】:

  • 你有什么?您需要帮助哪些部分?您将需要 SIGINT 的信号处理程序(但可能不需要 SIGCONT)。因此,您应该查看sigaction()。我假设你的信号量代码已经在工作了?
  • 重复? *.com/questions/284325/… 包含一个很好的答案。
  • @JonathanLeffler 信号量部分对我来说工作正常。我坚持的是在按 ctrl-c 退出子进程应该首先在文件中更新每个使用资源的次数的部分。此后,孩子和父母相继终止。
  • 我尝试过这样的事情......但不知道它是否正确。我使用 signal(SIGINT, handler) 来处理父进程中的 SIGINT,然后将 kill(0,SIGQUIT) 作为处理函数的一部分发送到整个进程组。但是写入文件的问题仍然需要解决
  • @ritz - 发布你已经完成的工作。

标签: c fork parent-child


【解决方案1】:

正式的信号处理函数应该尽可能少做。 C 标准说它可以写入volatile sig_atomic_t 变量,或调用abort()_Exit()(或者,有限制,signal())。 POSIX 允许发生更多事情,而且您可能正在使用 Linux(尽管您没有这么说)。因此,您的信号处理程序会将 sig_atomic_t 变量的值从 0 更改为 1,以表明信号已发生。

因此,您的子进程将循环。作为循环条件的一部分,您应该检查sig_atomic_t 变量以查看子级是否应该终止。当它检测到信号发生时,它将停止循环,打开日志文件进行追加,将其信息写入该文件,然后退出。您可以在处理中的其他点检查sig_atomic_t 变量,而不仅仅是主循环条件;那是你的决定。

请注意,您应该使用sigaction() 而不是signal() 来控制信号处理,并且您应该在处理信号时阻止中断。

所以,总结一下:

  • 您的信号处理程序做的越少越好。
  • 您的代码在主循环中检测到何时调用了信号处理程序并安排退出。
  • 您的代码还可以检测何时在其他方便的位置调用了信号处理程序。
  • 您可以调用函数进行日志记录并退出。

【讨论】:

    【解决方案2】:

    为了写入文件,您需要在 SIGINT 的信号处理程序中添加要写入所述文件的代码。如果您希望每个进程都写入该文件,则需要确保将 SIGINT 发送到整个进程组。

    您可能无需向每个进程发送 SIGQUIT,因为您可以让每个进程在处理 SIGINT 后简单地退出。如果你想稍微优化一下,你可以保留一个共享数据结构,其中进程已经收到了 SIGINT,这样你就不会向每个进程发送几个 SIGINT。

    【讨论】: