我的总体目标是将报告信息传递到命名管道,如果(并且仅当)有一个读取器连接到该命名管道.如果没有读者,我想避免构建报告信息等.由于这是在通过select()处理其他数据流的情况下发生的,我想将命名管道添加到“已准备好写入”的流中”.
所以,我想打开一个用于编写的命名管道,并且需要以某种方式将它提供给select(),以便select()仅在命名管道的另一端有一个读取器时返回.
通常情况下,如果没有读卡器,则打开电话已挂起;不幸的是,我不能给select()打开一个动作 – 只有打开的文件描述符是有效的.
为了得到一个像样的文件描述符,我正在创建一个虚拟阅读器(我打开命名管道来自己阅读),然后打开它进行写入,然后再次关闭虚拟阅读器:
dummy = os.open(fifoPath, os.O_RDONLY | os.O_NONBLOCK)
# ^^^ without the NONBLOCK, this will hang until another process is ready to write
fifo = os.open(fifoPath os.O_WRONLY)
os.close(dummy)
如果我现在打开另一个读者,他将收到我写入命名管道的内容,因此这方面是有效的.
但是现在select()总是将fifo返回为ready-to-write,即使没有连接读取器:
r, w, e = select.select([], [ fifo ], [])
print w[0]
这将始终立即打印fifo值.
无论我写多少,写入命名管道也不会挂起:
fifo.write('foo')
由于没有连接读卡器,我写的数据就丢失了.
打开我的虚拟阅读器时,我正在传递标志O_NONBLOCK,否则这个开头也会挂起.我尝试了各种方法,但无法弄清楚如何正确地做到这一点.
任何人都可以告诉我如何将命名管道与select()结合使用?
(上面的代码是在Python中,但我想问题并不是真的与Python有关,而是与Linux / Unix有关,所以我不会将这个问题标记为Python.)