将signalfd发送到另一个进程

时间:2014-11-02 15:48:50

标签: linux signals ipc

进程A向进程B发送signalfd.B尝试read()时会发生什么?如果B将signalfd添加到epoll,epoll_wait何时返回?

2 个答案:

答案 0 :(得分:1)

手册页中有一条线索:

  

fork(2)语义

     

在fork(2)之后,子进程继承了signalfd文件描述符的副本。从子文件描述符中读取(2)将返回有关排队到子项的信号的信息。

通过unix socket传输的

signalfd应该与fork()继承的行为相同。基本上,哪个过程创建signalfd无关紧要; read()始终返回排队到调用read()的进程的信号。

epoll存在奇怪的交互,但是:由于epoll事件队列是在任何特定进程的上下文之外进行管理的,因此它根据所有进程决定signalfd的准备情况。最初调用epoll_ctl()以注册对signalfd的兴趣的过程。因此,如果您安排使用signalfd FD观看epoll,然后将两个FD发送到另一个进程,则接收过程将看到不一致的结果:epoll仅在发送时发出信号准备就绪process有一个信号,但signalfd将返回接收过程的信号。

这种情况特别容易使用fork()。例如,如果初始化事件循环库而不是使用epollsignalfd,则调用fork()(例如,为了守护进程),然后尝试在子进程中使用该库,你可能会发现你无法接收信号。 (我昨天花了一整天时间试图调试这样的问题。)

答案 1 :(得分:-1)

这是不一致的,或至少是一个记录不足的角落案例。仔细阅读 signal(7)

进程A可以使用kill(2)killpg(2)向进程B发送信号(而不是signalfd)。

进程B处理信号(并且有一些默认行为来处理某些信号)。它可以使用旧的signal(2)或更新的sigaction(2)安装(以POSIX标准方式)信号处理程序,或者可以使用signalfd(2)来获取(以Linux特定的方式)文件描述符上的一些数据。

因此,signalfd为成功提供了一个新的文件描述符,例如opensocket

阅读signalfd(2)文档,它解释了B端读取时发生了什么(内核正在发送一些struct signalfd_siginfo,我想从获取信号的过程的角度来看,而不是读取文件描述符的过程,请参阅内核的源文件fs/signalfd.c),或者在poll给出的文件描述符上等待signalfd epoll ;当B接收到信号时,轮询将成功。

成功的signalfd只是获取打开的文件描述符(如文件描述符opensocketaccept,{{1你给了你)并且你不会与不相关的进程共享那个文件描述符。

如果您敢于使用sendmsg(2)套接字在unix(7)套接字上使用pipe向其他进程发送该文件描述符,我将不会做出任何假设。我想它类似于pipe(7) - s或fifo(7) - s或netlink(7) - s。但我当然不会这样做:SCM_RIGHTS是特定于Linux的,并且您处于无证件角落情况。阅读内核源代码以了解正在发生的事情,或在kernelnewbies上询问。并且不要指望未来的内核在未记录的方面与现有内核保持一致......