在库(2)调用中禁用SIGPIPE信号

当写入pipe() FD时,是否可以禁止引发信号SIGPIPE ), 而无需安装自己的信号处理程序或全局禁用/屏蔽信号?


背景

我正在创build一个偶尔创build一个pipe道的小型库,而fork()是一个等待来自父级的消息的临时子/虚拟进程。 当subprocess收到来自父进程的消息时,就会死(有意)。


问题

对于超出我的控制范围的情况,subprocess运行易于崩溃的另一个(第三方)库的代码,所以在write()到pipe道之前,我不能始终确定subprocess是活动的。

这导致我有时试图write()到subprocess'end已经死/封闭的pipe道,并在父进程中引发SIGPIPE 。 我在其他客户将要使用的图书馆 ,所以我的图书馆必须尽可能独立和透明的调用应用程序。 安装自定义信号处理程序可能会破坏客户的代码。


到目前为止工作

我已经通过使用setsockopt(..., MSG_NOSIGNAL)与套接字解决了这个问题,但我找不到任何function等同于pipe道。 我已经看了临时安装一个信号处理程序来捕获SIGPIPE ,但我没有看到任何方法来限制它的范围,而不是整个过程中的调用函数(而不是primefaces)。

我也在SO上发现了一个类似的问题,就是要求同样的事情,但是不幸的是,使用poll() / select()不会是primefaces的,并且subprocess之间的远程(但可能)我的select()write()调用。


问题(还原)

有没有什么办法来实现我在这里尝试,或者自动检查和写入pipe道而不触发将产生SIGPIPE的行为? 此外,是否有可能实现这一点, 知道如果儿童进程坠毁? 知道它是否崩溃让我build立供应商提供“crashy”库的情况,并让他们知道失败的频率。

写入pipe() FD […]时是否可以禁用信号( SIGPIPE )的提升?

父进程可以保持打开管道的读取结束的副本。 那么总会有一个读者,即使它没有真正阅读,所以SIGPIPE的条件永远不会被满足。

问题在于这是一个僵局风险。 如果孩子死亡,之后家长执行阻塞写入,不能容纳在管道的缓冲区中,那么你要烤面包。 没有任何东西会从管道中读取以释放任何空间,因此写入永远不会完成。 首先避免这个问题是SIGPIPE的目的之一。

您也可以在尝试写入之前通过waitpid()选项WNOHANG来测试孩子是否还活着。 但是这引入了竞争条件,因为孩子可能会在waitpid()和write之间死亡。

然而,如果你的写操作一直很小,并且如果你从孩子那里得到足够的反馈信息来确信管道缓冲区没有备份,那么你可以把这两者结合起来,形成一个合理可行的系统。

不知道我遵循: 是父进程,即写入管道。 您这样做是为了在一段时间后发送消息。 子进程以某种方式解释消息,做它要做的事情并退出。 你也必须等待,你不能先准备好消息,然后产生一个孩子来处理它。 也只是发送一个信号不会做的伎俩,因为孩子必须真正的行事的消息的内容,而不仅仅是“做”的电话。

首先想到的是,你不会关闭父级管道的读取面。 这可以让你自由地写信给管道,同时又不伤害孩子的阅读能力。

如果这不好,请详细说明这个问题。

经过一切可能的途径解决这个问题后,我发现只有两个地方可以解决这个问题:

  • 使用socketpair(PF_LOCAL, SOCK_STREAM, 0, fd)来代替管道。
  • 通过fork()创建一个“牺牲”子进程,如果引发SIGPIPE ,允许它崩溃。

我去了socketpair路线。 我不想这样做,因为它涉及重新编写一些管道逻辑,但这不是太痛苦。

谢谢!