Select weirdness

Donn Cave donn at u.washington.edu
Mon Apr 23 13:13:55 EDT 2007


In article <rNOSPAMon-934744.11420922042007 at news.gha.chartermi.net>,
 Ron Garret <rNOSPAMon at flownet.com> wrote:

> The answer is obvious: select is looking only at the underlying socket, 
> and not at the rfile buffers.
> 
> So... is this a bug in select?  Or a bug in my code?

Yes.

I don't see any specific followup to this point, but it is or
at least should be a well known limitation of C library I/O and
select.  select() is an operating system function that has no
way to know the state of your process I/O buffers, nor do the C
stdio buffers don't come with a standard way to inspect that state.
Therefore, if you mix C I/O with select(), you're more or less out
of luck.  This applies directly to Python, because it calls the
operating system select() function and it uses C stdio buffers for
its file object (and entices you to make this mistake by supporting
a file object as an input to select().)

This conflict can be relieved after a fashion by eliminating the
buffer.  The now unbuffered C fgets / Python readline won't store
extra lines that select can't see, but the semantics of the operation
are still a poor fit with the usual application of select.  The
number of system-level I/O calls is significantly greater as you
transfer data one byte at a time, which may add a lot of overhead
if you transfer a lot of data, and your readline() function still
can't return until it gets that '\n', so a half line can block your
application.

It isn't a lot of work to read data with operating system functions
that are compatible with select - os.read(), socket.recv() - and
break it up into lines on your own, and this completely and efficiently
resolves the problem.

I haven't looked at your code.

   Donn Cave, donn at u.washington.edu



More information about the Python-list mailing list