Как читать имя FIFO не блокируемо?

Я создаю FIFO и периодически открываю его в режиме только для чтения и без блокировки из a.py:

os.mkfifo(cs_cmd_fifo_file, 0777)
io = os.open(fifo, os.O_RDONLY | os.O_NONBLOCK)
buffer = os.read(io, BUFFER_SIZE)

От b.py откройте fifo для записи:

out = open(fifo, 'w')
out.write('sth')

Затем a.py вызовет ошибку:

buffer = os.read(io, BUFFER_SIZE)
OSError: [Errno 11] Resource temporarily unavailable

Кто-нибудь знает, что случилось?

2 ответа

Согласно man-странице read(2):

EAGAIN or EWOULDBLOCK
 The file descriptor fd refers to a socket and has been marked
 nonblocking (O_NONBLOCK), and the read would block.
 POSIX.1-2001 allows either error to be returned for this case,
 and does not require these constants to have the same value, so
 a portable application should check for both possibilities.

Итак, что вы получаете, так это то, что для чтения нет данных. Безопасно обрабатывать такую ​​ошибку:

try:
 buffer = os.read(io, BUFFER_SIZE)
except OSError as err:
 if err.errno == errno.EAGAIN or err.errno == errno.EWOULDBLOCK:
 buffer = None
 else:
 raise # something else has happened -- better reraise
if buffer is None: 
 # nothing was received -- do something else
else:
 # buffer contains some received data -- do something with it

Убедитесь, что импортирован модуль errno: import errno.


out = open(fifo, 'w')

Кто закроет его для вас? Замените Open + на запись следующим образом:

with open(fifo, 'w') as fp:
 fp.write('sth')

UPD: Хорошо, просто сделайте это:

out = os.open(fifo, os.O_NONBLOCK | os.O_WRONLY)
os.write(out, 'tetet')

licensed under cc by-sa 3.0 with attribution.