代码之家  ›  专栏  ›  技术社区  ›  P Shved

我应该担心在一个进程中哪个进程接收信号的顺序吗?

  •  4
  • P Shved  · 技术社区  · 14 年前

    我想通过发送 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) ,而master仍然不是,master可能会将此报告为内部故障(在收到子级已死亡的通知时)。但是,我希望所有流程都理解,这种终止是由流程组外部的事物引起的。

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

    注意,我不能修改组中进程的代码!

    4 回复  |  直到 14 年前
        1
  •  5
  •   camh    14 年前

    尝试将其作为三个步骤进行:

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

    第一个sigstop应该将所有进程置于停止状态。它们无法捕获此信号,因此应该停止整个进程组。

    sigterm将排队等待进程,但我不相信它会被传递,因为进程被停止(这是从内存中获取的,我目前找不到引用,但我相信它是真的)。

    SIGCont将再次启动进程,允许传递SIGTERM。如果从机先得到信号控制,那么主机可能仍然会停止,因此它不会注意到从机离开。当主设备获得SIGCont时,它后面跟着SIGTerm,终止它。

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

        2
  •  1
  •   Marius Gedminas    14 年前

    我的理解是,您不能依赖于任何特定的信号发送顺序。

    如果只向主进程发送术语信号,然后让主进程杀死其子进程,则可以避免此问题。

        3
  •  1
  •   Darron    14 年前

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

    即使您的停止/定期/连续序列也容易受到影响。

    恐怕你需要更复杂的东西。也许子进程可以捕获sigterm,然后循环直到父进程退出,然后再退出自己?如果这样做,请确保并添加超时。

        4
  •  0
  •   mvds    14 年前

    未测试:使用共享内存并放入某种“我们快死了”信号量,在将I/O错误视为真正的错误之前,可以检查这些信号量。与map_anonymous_map_共享的mmap(),确保它能以您的方式 fork() ING过程。

    哦,一定要用 volatile 关键字或信号量被优化掉了。