1

我正在尝试处理如下工作的服务器:

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

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

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

但是,我关心的是父进程启动以执行命令的某些进程可能有自己的管道对它们开放。如果写入 THOSE 管道失败,我想简单地忽略 SIGPIPE。

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

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

  • local $SIG{PIPE}在写入该管道之前设置 helper-process-specific
  • print $HELPER_PIPE(这只发生在一个子程序中)
  • 将 $SIG{PIPE} 重置为DEFAULTIGNORE
  • 确保这 3 个操作在它们自己的块范围内。
4

2 回答 2

5

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

于 2014-03-29T02:15:18.827 回答
3

便携你看不出来。但是,您可能会发现您的操作系统支持该SIG_INFO信息,并且如果您能以某种方式将其升级到 Perl,则该siginfo结构包含一个字段,该字段提供 FD 编号SIGPIPE

于 2014-03-29T15:29:21.570 回答