我是否应该担心订单流程中的流程接收信号?

时间:2010-07-10 11:32:47

标签: linux process signals

我希望通过向其中的进程发送SIGTERM来终止进程组。这可以通过kill命令完成,但我找到的手册提供了有关其工作原理的一些细节:

   int kill(pid_t pid, int sig);
   ...
   If pid is less than -1, then sig is sent to every  process  in
   the process group whose ID is -pid.

但是,信号将以哪种顺序发送到组成组的进程?想象一下以下情况:在组中的主进程和从进程之间设置管道。如果在处理kill(-pid)期间奴隶被杀死,而主人仍然没有,则主人可能会将此报告为内部失败(收到孩子死亡的通知后)。但是,我希望所有进程都能理解这种终止是由其进程组外部的东西引起的。

我怎样才能避免这种混乱?我应该做的不仅仅是kill(-pid,SIGTERM)吗?或者它是由操作系统的底层属性解决的,我不知道它?

请注意,我无法修改组中进程的代码!

4 个答案:

答案 0 :(得分:5)

尝试将其分为三个步骤:

kill(-pid, SIGSTOP);
kill(-pid, SIGTERM);
kill(-pid, SIGCONT);

第一个SIGSTOP应该将所有进程置于停止状态。他们无法捕获这个信号,所以这应该会阻止整个过程组。

SIGTERM将排队等待进程,但我不相信它会被传递,因为进程已停止(这是来自内存,我目前无法找到引用,但我相信这是真的)。

SIGCONT将再次启动流程,允许交付SIGTERM。如果从机首先获得SIGCONT,则主机可能仍然停止,因此它不会注意到从机离开。当主服务器获得SIGCONT时,它将跟随SIGTERM,终止它。

我不知道这是否真的有效,而且可能是实现取决于所有信号何时实际传递(包括SIGCHLD到主进程),但可能值得一试。

答案 1 :(得分:1)

我的理解是你不能依赖任何特定的信号传递顺序。

如果您仅将TERM信号发送到主进程,然后让主服务器终止其子进程,则可以避免此问题。

答案 2 :(得分:1)

即使所有各种类型的UNIX都承诺以特定顺序传递信号,调度程序仍可能决定在父代码之前运行关键子进程代码。

即使你的STOP / TERM / CONT序列也容易受此影响。

我担心你可能需要更复杂的东西。也许子进程可以捕获SIGTERM然后循环,直到它的父进程退出它之前?如果你这样做,请确保并添加超时。

答案 3 :(得分:0)

未经测试:使用共享内存并输入某种“我们正在死亡”的信号量,可以在将I / O错误视为真正的错误之前进行检查。 mmap()使用MAP_ANONYMOUS | MAP_SHARED,并确保它能够在fork()进程中保持不变。

哦,请务必使用volatile关键字,否则您的信号量就会被优化掉。