【问题标题】:Preventing SIGPIPE防止 SIGPIPE
【发布时间】:2012-07-03 09:51:00
【问题描述】:

让我们考虑以下示例。

我有一个父进程创建一个管道,生成一个子进程并使用该管道读取子进程的标准输出。在某些时候,父进程不再对子进程的输出感兴趣,并关闭管道的读取端。

显然,如果孩子继续写,这是否会导致子进程收到SIGPIPE信号。

问题:有没有办法将子进程的输出重定向到/dev/null,以便它仍然继续运行并产生输出,但父进程可以继续做其他事情并稍后在子进程上调用waitpid?请注意,将孩子的 SIGPIPE 处理程序设置为 SIG_IGN 不是一个选项,因为我无法控制孩子的信号处理程序。

【问题讨论】:

  • 下面 Gergely 和 sarnold 的建议基本正确。但请注意,SIGPIPE 的存在是有原因的:如果您没有它,生成输出的进程将一直旋转到输入的末尾(可能是永远)而不是退出——诸如“更多”或“头”之类的工具/tail" 将无法写入。你确定这是你想要的行为吗?

标签: linux signals posix ipc sigpipe


【解决方案1】:

请注意,将孩子的 SIGPIPE 处理程序设置为 SIG_IGN 不是一个选项,因为我无法控制孩子的信号处理程序。

将其包装在一个简单的二进制文件中。 (顺便说一句,即使是 shellscript 也可以。)

【讨论】:

  • 这将防止 SIGPIPE 导致死亡,假设子进程没有将其信号处理程序重置为 SIG_DFL。但随后它会从 write() 中得到一个 EPIPE 错误,这可能会导致它抱怨并退出。
  • .. 虽然我很难看到一个孩子到底会怎么做,这个孩子一直在跑步,但被忽略了。 :)
  • @sarnold: 好吧,最后你可以在 chrooted 环境中执行nohup binary.bin > /dev/null < /dev/zero,最好是在 Xen 下:D 这将是终极的“不听不看不看”说话”程序:)
  • 你可以在fork()返回0之后和执行子进程之前将SIGPIPE设置为SIG_IGN。假设孩子没有明确地重置它,那么孩子将永远不会收到SIGPIPE。 (尽管它的写入会得到 Alan 提到的 EPIPE 错误。)
【解决方案2】:

自己模拟/dev/null -- fork() 一个新进程,其工作是读取并忽略子进程的输出。

【讨论】:

    【解决方案3】:

    当两个组件之间的管道破裂时会发生信号管道。

    您可以通过以下方式忽略信号管

    信号(SIGPIPE,SIG_IGN);

    【讨论】:

      猜你喜欢
      • 2011-10-12
      • 2011-12-20
      • 1970-01-01
      • 2023-03-25
      • 1970-01-01
      • 1970-01-01
      • 2011-10-13
      • 1970-01-01
      相关资源
      最近更新 更多