有没有办法让作者知道读者已经关闭了命名管道(或退出)的末尾而没有写入它?
我需要知道这一点,因为我写入管道的初始数据是不同的; 读者期望在其余数据到来之前有一个初始标题.
目前,当我write()失败时,我会发现这一点EPIPE.然后我设置了一个标志,上面写着"下次发送标题".但是,在我写任何东西之前,读者可以关闭并重新打开管道.在这种情况下,我从来没有意识到他做了什么,也没有发送他期待的标题.
是否存在任何类型的异步事件类型可能对此有帮助?我没有看到任何信号被发送.
请注意,我没有包含任何语言标记,因为这个问题应该被视为与语言无关.我的代码是Python,但答案应该适用于C或任何其他具有系统调用级绑定的语言.
奇怪的是,当最后一个读取器关闭管道时,select表明该管道是可读的:
作家.py
#!/usr/bin/env python
import os
import select
import time
NAME = 'fifo2'
os.mkfifo(NAME)
def select_test(fd, r=True, w=True, x=True):
rset = [fd] if r else []
wset = [fd] if w else []
xset = [fd] if x else []
t0 = time.time()
r,w,x = select.select(rset, wset, xset)
print 'After {0} sec:'.format(time.time() - t0)
if fd in r: print ' {0} is readable'.format(fd)
if fd in w: print ' {0} is writable'.format(fd)
if fd in x: print ' {0} is exceptional'.format(fd)
try:
fd = os.open(NAME, os.O_WRONLY)
print '{0} opened for writing'.format(NAME)
print 'select 1'
select_test(fd)
os.write(fd, 'test')
print 'wrote data'
print 'select 2'
select_test(fd)
print 'select 3 (no write)'
select_test(fd, w=False)
finally:
os.unlink(NAME)
Run Code Online (Sandbox Code Playgroud)
演示:
1号航站楼:
$ ./pipe_example_simple.py
fifo2 opened for writing
select 1
After 1.59740447998e-05 sec:
3 is writable
wrote data
select 2
After 2.86102294922e-06 sec:
3 is writable
select 3 (no write)
After 2.15910816193 sec:
3 is readable
Run Code Online (Sandbox Code Playgroud)
2 号航站楼:
$ cat fifo2
test
# (wait a sec, then Ctrl+C)
Run Code Online (Sandbox Code Playgroud)