如何避免使用并行命名管道死锁?

时间:2015-02-04 02:00:53

标签: linux shell unix named-pipes fifo

我正在研究a flow-based programming system called net2sh。它目前基于通过命名管道连接的shell工具。多个流程协同工作以完成工作,通过命名管道进行通信,与工厂中的生产线不同。

总的来说,它工作得非常好,但是有一个主要问题。在进程通过两个或多个命名管道进行通信的情况下,“发送”进程和“接收”进程必须以相同的顺序打开管道。这是因为当进程打开命名管道时,它会阻塞,直到另一端也被打开。

我想要一种避免这种情况的方法,不需要为每个管道产生额外的“帮助”进程,而不必破解现有组件,也不必乱用程序网络来避免这个问题。

理想情况下,我正在寻找一些“非阻塞fifo”选项,其中fifo上的“open”总是立即成功但后续操作可能会阻塞,如果管道缓冲区已满(或空,读取)......我甚至考虑使用内核补丁来实现这种效果。根据fifo(7),O_NONBLOCK确实在打开fifos时做了一些不同的事情,而不是我想要的东西,并且为了使用它我将不得不重写每个现有的shell工具,如cat。

这是一个死锁的最小例子:

mkfifo a b
(> a; > b; ) &
(< b; < a; ) &
wait

如果你能帮助我明智地解决这个问题,我将非常感激!

1 个答案:

答案 0 :(得分:2)

在这里使用O_NONBLOCK命名管道有一个很好的描述:How do I perform a non-blocking fopen on a named pipe (mkfifo)?

听起来您希望它在整个环境中工作而不更改任何C代码。因此,一种方法是将LD_PRELOAD设置为某个共享库,该库包含open(2)的包装器,只要O_NONBLOCK引用flags,就会pathname添加LD_PRELOAD命名管道。

使用{{1}}覆盖库函数的简明示例如下:https://www.technovelty.org/c/using-ld_preload-to-override-a-function.html

这是否真的在实践中有效而不打破其他任何事情,你必须自己找出来(请告诉我们!)。