是否有可能检测到哪个管道扔了一个SIGPIPE?

时间:2014-03-28 23:40:22

标签: perl pipe ipc sigpipe

我试图处理一个如下工作的服务器:

  • 它有一个父进程
  • 它创造了一个帮助"子进程来处理一些特殊任务
    • 用管道打开子进程;并使用管道向子项发出命令。
  • 它还会产生许多其他子进程(服务器的主要目标是执行各种命令)。

我希望能够检测到子进程的管道写入失败的时间;并发出特别通知。

通常,我会通过在父进程中创建自定义$SIG{PIPE}处理程序来实现这一目的。

然而,我所关心的是,父启动执行命令的某些进程可能会打开自己的管道;如果对THOSE管道的写入失败,我想完全忽略SIGPIPE。

Q1。有没有办法让我从SIGPIPE处理程序中告诉,哪个打开的管道发出了信号? (我知道每个孩子的PID,所以PID会很好......或者如果通过文件描述符#s可以做到这一点?)。

Q2。我可以用local $SIG{PIPE}以某种方式解决问题吗?我的假设是我需要:

  • 在写入该管道之前设置特定于助手进程的local $SIG{PIPE}
  • 执行print $HELPER_PIPE(这只发生在一个子程序中)
  • 将$ SIG {PIPE}重置为DEFAULTIGNORE
  • 确保这3个操作都在他们自己的块范围内。

2 个答案:

答案 0 :(得分:5)

write系统调用在触发EPIPE的情况下返回错误SIGPIPE,假设SIGPIPE未成功终止进程。因此,最好的办法是设置$SIG{PIPE} = 'IGNORE'(以避免死于信号),使用$fh->autoflush(以避免PerlIO缓冲,确保立即通知您任何I / O错误),以及每次调用时都要检查print的返回值。如果print返回false并且设置了$!{EPIPE},那么您已尝试写入已关闭的管道。如果print返回false并且未设置$!{EPIPE},则还有其他问题需要处理。

答案 1 :(得分:3)

你可以告诉他。但是,您可能会发现您的操作系统支持SIG_INFO信息,如果您能以某种方式获得Perl,则siginfo结构包含一个字段,该字段在SIGPIPE上提供FD编号。 / p>