我在FIFO上有读写器,读卡器不能无限期阻塞。为此,我用O_NONBLOCK
打开read end。在
写入端可能会阻塞,因此我将其作为常规文件打开。大的写操作执行得不可接受,非常糟糕-读/写4MB块需要几分钟,而不是预期的几秒钟(这是预期的,因为在linux中相同的代码只需几秒钟)。在
在Python中复制问题的示例代码。首先,使用mkfifo
创建一个fifo,例如mkfifo some_fifo
,然后运行读取端,然后运行写入端。在
阅读结束:
import os, time
# mkfifo some_fifo before starting python
fd = os.open('some_fifo',os.O_RDONLY | os.O_NONBLOCK)
while True:
try:
read = len(os.read(fd, 8192)) # read up to 8kb (FIFO buffer size in mac os)
print(read)
should_block = read < 8192 # linux
except BlockingIOError:
should_block = True # mac os
if should_block:
print('blocking')
time.sleep(0.5)
写入结束:
^{pr2}$注意:我在这个问题上碰到的原始代码是跨平台的Java代码,它也运行在linux上。不幸的是,这意味着我不能将kqueue与kevent的data
字段一起使用来计算在不阻塞的情况下我可以读取多少数据—这些数据在我使用的epoll/kqueue抽象中丢失了。这意味着使用阻塞fd à la this answer的解决方案是不可接受的。在
编辑:原始代码在读取端使用kqueue来阻塞文件描述符,这会使更糟
edit2:Linuxos.read()
在连接管道的另一端之前不会抛出BlockingIOError,尽管文档声明应该这样做(调用成功(返回0),但将errno设置为EAGAIN)。更新了代码,以便对linux行为也很友好。在
编辑3:macOS的代码最初是: 在
^{3}$这与sleeps版本的性能一样差,但是sleep可以确保问题不出在阻塞机制上,而且是跨平台的。在
目前没有回答
相关问题 更多 >
编程相关推荐