从命名管道并发选择

标签 c unix concurrency named-pipes manualresetevent

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

是否有关于此的任何规范,或者这是否取决于系统?

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

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

谢谢。

最佳答案

If a writer comes in and writes, say one byte to this fifo, will all blocked select() calls return simultaneously or will only one thread be chosen and return from select()?

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

Is there any specification on this or would this be system-dependent?

这将取决于系统、应用程序布局和代码结构。这将是一个很好的未定义行为。

The reason i m asking is that i want to implement Windows-like manual reset events using fifos.

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

即,执行以下操作:

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

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

关于从命名管道并发选择,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18710426/

相关文章:

c - 在子进程中使用 fork() 的斐波那契

linux - 如何在 Linux 后台终止作业调度程序?

c - 套接字 : Byte order mixed up

java - 收到 ConcurrentModificationException 但我没有删除

java - 在 catch block 中调用 ReentrantReadWriteLock#lock() 是否错误?

java - 这个多线程代码保证总是返回零吗?

c - 从另一个进程中加载​​的 dylib 读取数据字段

c - 尝试将 str 写入具有特殊文件名 "con"的文件,但它被打印到 stdout

c - 使用 memset 时,数组未正确重置

linux - 我的linux系统上安装了gcc,仍然安装失败