并发从命名管道中选择

时间:2013-09-10 03:50:54

标签: c unix concurrency named-pipes manualresetevent

假设我有一个fifo(命名管道),它可以从多个进程或线程多次打开。所有这些都将同时调用select()进行读取。如果一个作者进来写入,比如说这个fifo的一个字节,所有被阻止的select()调用会同时返回,还是只选择一个线程并从select()返回?

是否有任何相关规范或是否与系统有关?

我问的原因是我想使用fifos实现类似Windows的手动重置事件。手动重置事件要求在发出事件信号时,将释放所有等待线程(不仅仅是自动重置事件中的一个)。

我可以使用pthread conds,但我的要求是由多个进程共享事件。

感谢。

1 个答案:

答案 0 :(得分:1)

  

如果一个作家进来写道,比如说这个fifo的一个字节,那就是全部   阻塞的select()调用同时返回或只有一个线程   选择并从select()返回?

会有竞争条件。系统将开始以某种随机顺序唤醒线程,直到其中一个读取数据,清空缓冲区并阻止其他线程唤醒。

  

是否有任何相关规范或是否与系统有关?

这取决于系统,应用程序布局,代码结构。这将是一个伟大的未定义的行为。

  

我问的原因是我想使用fifos实现类似Windows的手动重置事件。

你在Linux / Posix上编码吗?使用tee函数而不是read,让线程将一些状态代码写回管道,以表示它们已经唤醒。然后,通过在控制线程中读回数据来重置管道。

即,执行以下操作:

在工作线程中:选择(和阻止)。 在控制线程中:写一个字节。现在,选择不会阻塞。 工作线程被唤醒。现在在工作线程中执行一个可选的tee(一个字节),并在每个线程中将一个字节写回管道。 在控制线程中:读取和计数字节。如果所有工作线程波都被唤醒,请再读一个字节以擦除您编写的第一个字节。 选择现在再次阻止。

请注意,在完成整个过程之前,您无法再次输入选择。你可能需要两个这样的管道。