non-blocking IO EAGAIN on write

John Nagle nagle at animats.com
Sat Jul 24 14:23:49 EDT 2010


On 7/23/2010 1:45 AM, Thomas Guettler wrote:
> Hi,
>
> I use non-blocking io to check for timeouts. Sometimes I get EAGAIN (Resource temporarily unavailable)
> on write(). My working code looks like this. But I am unsure how many bytes have been written to the
> pipe if I get an EAGAIN IOError.

    At the OS level, if you get EAGAIN, no bytes have been written.  If 
you get EOK from a non-blocking request, you must check the number of
bytes written to see if everything was written.  You may have to write
more after an EOK.

Ref: http://www.opengroup.org/onlinepubs/009695399/functions/write.html

"If the O_NONBLOCK flag is set, write() shall not block the thread. If 
some data can be written without blocking the thread, write() shall 
write what it can and return the number of bytes written. Otherwise, it 
shall return -1 and set errno to [EAGAIN]."

    At the Python level, it's different.

	http://docs.python.org/library/stdtypes.html#file-objects

says that "file.write(s)" returns nothing.  If a non-blocking write
can't complete, you get an  "io.BlockingIOError" exception

(ref "http://docs.python.org/release/3.0.1/library/io.html")

from which you can retrieve the number of bytes written.
This is only in Python 3.x, and may not be working right
(ref "http://bugs.python.org/issue7786").  It's unclear
what happens in this situation in Python 2.x, but it's
probably not what you wanted to happen.

    However, "socket.send(s)" returns the number of bytes sent.
"send" and "recv" do work on pipes (with problems; see 
"http://bugs.python.org/issue5573").  So
use "send", not "write", and pay attention to the number of bytes
sent.

> If I get EAGAIN can I just sleep, and then retry with the same data chunk?

     Yes. But if you've filled the pipe, you may have to wait until the
program reading from the pipe reads more.  This can take however long
the other program needs.

     Incidentally, "select" apparently doesn't work on pipes under
Windows.

     Since your code isn't doing anything else while waiting for a
write to complete on the pipe, why use non-blocking I/O at all?

(I know, the Python I/O timeout logic is broken in some versions.
You're probably working around that.)

					John Nagle





More information about the Python-list mailing list