【问题标题】:open on FIFO (named pipe) freezes - ignores SIGINT, SIGTERM打开 FIFO(命名管道)冻结 - 忽略 SIGINT、SIGTERM
【发布时间】:2015-05-29 22:25:55
【问题描述】:

我正在使用命名管道在分叉的进程之间进行通信。每个进程处理SIGINTSIGTERM,然后关闭它的管道末端并进行清理。

如果信号在我 fork 进程时正确发生,则该进程会在尝试打开管道时挂起(因为另一端已经关闭它 - 或者另一端可能不再初始化)。

现在我的应用程序卡在等待管道打开。因为进程是相互通信的分叉兄弟,所以我不能确定进程 A 是否在进程 B 之前设置了它的管道末端 - 即我看不到使用 O_NONBLOCK 的方法(至少没有连续正在尝试设置它)。

从管道读取时,信号似乎可以很好地中止它。只是管子的开口被锁住了。

有什么想法吗?

【问题讨论】:

  • 分叉和打开管道之间,终止时拒绝关闭?甚至可以告诉另一端你有一个终止,然后干净地关闭?
  • 我猜主要问题是每个进程自己处理信号,因此可以在另一个进程处理它之前关闭连接。我可以检查我是否在分叉之前收到信号,但这仍然会留下一个很小的时间窗口,可以在其中提升信号并且我仍然分叉+打开。我想我只能在等待它打开(或信号)时尝试使用O_NONBLOCK...
  • 分叉前不能在parent中打开fifo的两端吗?然后让每个进程在分叉后关闭它不需要的描述符。
  • 你的单个处理程序,如果你是 post-fork,不要终止。相反,他们设置了一个标志,上面写着“我应该终止”。然后你通过管道发送一条消息说“我已被终止”。如果您从管道的另一端收到“我已被终止”的消息,请设置“我应该终止”标志,然后回复“我已被终止”。当你们都“我应该终止”并且从另一端得到“我已经终止”时,你关闭管道。 (这假设一个 2-way 通信通道)
  • 我无法在分叉之前打开两端,因为如果另一个进程正在终止,打开任何一端都会阻塞。我也没有双向通信,我更愿意使用信号来传达关闭的需要。

标签: c++ linux signals named-pipes freeze


【解决方案1】:

我改为采用非阻塞方法。我忙着等待(短暂的睡眠),直到管道建立或发出终止信号。

阅读和写作的工作方式类似。如果没有数据可用(读取 0 字节),那么我等待并重试。如果出现错误,我会处理它,如果没有发出信号,请重试(因为这需要在后台运行,而不是关闭应用程序)。

仅仅为了同步关机(加上正确处理)而设置一个额外的通信通道是相当困难的。

【讨论】:

    猜你喜欢
    • 2012-07-31
    • 2017-06-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-03-07
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多