假设我有一个 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/