Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to read named FIFO non-blockingly?

Tags:

I create a FIFO, and periodically open it in read-only and non-blockingly mode from 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)

From b.py, open the fifo for writing:

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

Then a.py will raise an error:

buffer = os.read(io, BUFFER_SIZE)

OSError: [Errno 11] Resource temporarily unavailable

Anyone know what's wrong?

like image 488
chaonin Avatar asked Jan 15 '13 19:01

chaonin


People also ask

How do you open FIFO in non blocking mode?

A process can open a FIFO in nonblocking mode. In this case, opening for read-only succeeds even if no one has opened on the write side yet and opening for write-only fails with ENXIO (no such device or address) unless the other end has already been opened.

Is pipe read blocking?

Read/Write Are Blocking - when a process reads from a named pipe that has no data in it, the reading process is blocked. It does not receive an end of file (EOF) value, like when reading from a file.

What is non blocking IO in C?

Sometimes it's convenient to have I/O that doesn't block i.e we don't want a read call to block on one in case of input from the other. Solution for this is the given function: To specify non-blocking option: #include<fcntl. h> int fd; fcntl(fd, F_SETFL, O_NONBLOCK);

What does FIFO man?

FIFO (fly-in fly-out) is a popular working arrangement in the mining, construction, oil and gas industries. FIFO employees fly in to their work site for the duration of their roster, before flying home.


1 Answers

According to the manpage of 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.

So what you're getting is that there is no data available for reading. It is safe to handle the error like this:

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

Make sure you have the errno module imported: import errno.

like image 146
Jonas Schäfer Avatar answered Sep 21 '22 02:09

Jonas Schäfer