在Ctrl-C上终止父进程和子进程

时间:2012-01-13 18:09:29

标签: c fork parent-child

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

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

例如:

Process 1 - 5 times
Process 2 - 3 times

等等。

请在此实施中寻求帮助...

2 个答案:

答案 0 :(得分:2)

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

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

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

所以,总结一下:

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

答案 1 :(得分:0)

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

您可以在不向每个进程发送SIGQUIT的情况下完成,因为您可以让每个进程在处理SIGINT后自行退出。如果要优化一点,可以保留一个共享数据结构,其中哪些进程已经收到了SIGINT,这样就不会向每个进程发送多个SIGINT。