[Stackless] non-blocking IO in uthreads

Bernd Rinn Bernd.Rinn at epost.de
Fri Feb 9 18:04:39 CET 2001

On Fri, Feb 09, 2001 at 11:01:11AM -0500, Will Ware wrote:
> > [can nbselect() be sped up, as select() is taking too much time]
> You have a while loop that calls select() repeatedly. You can probably
> do better by calling select() less often. One simple way to do this
> would be to force a context switch after each iteration of the while
> loop:
>     while timeout < 0 or time() < tmax:
>         r,w,e = select(iwtd, owtd, ewtd, dt)
>         if r or w or e: break
>         uthread.switchContext()
>     return r,w,e
> You may find that you can afford to call select() even less frequently,
> probably easiest by using a counter.
>     i = 0
>     while timeout < 0 or time() < tmax:
>         if i == 10:
>             r,w,e = select(iwtd, owtd, ewtd, dt)
>             if r or w or e: break
>             i = 0
>         i = i + 1
>         uthread.switchContext()
>     return r,w,e

It seems that select() is not the expensive operation. The first code
snippet increases the load to 10% CPU usage, the second code snippet
to about 90% CPU-usage. I am not only concerned about what the other
uthreads get from the CPU but about the system as a whole. 

On Fri, 09 Feb 2001 11:46:55 -0500 Jeff Senn <senn at maya.com> wrote:
>Hey! I just wrote essentially the same code yesterday.  However in my
>version I provided a call that blocked the current thread and used a
>single uthread to gather up all of the selects and then unblock'd any
>uthreads found to have IO ready.  It's probably a better solution
>if your program is going to have a lot of IO pending -- since the
>various uthreads calling select don't have to fight it out.  (I've
>done no performance tests...yet).
>Also I did the select with a immediate timeout and then did a
>uthread.wait(...)  -- which is probably better if you have a lot of
>non-IO blocked uthreads running that you don't want to postpone.

I am trying to use uthreads to drive a threaded server. This server is
running as a daemon all the time and 99.9% of the time it spends in
the select() routine listening on a network socket for incoming
connections. So this has to be a cheap operation in terms of CPU
usage. While waiting in a select() system-call is cheap, executing a
python-loop and increasing a counter is not cheap. Also calling
uthread.wait() is rather expensive. When looking at the output of
'top' the old version (using Python's threading module) is (nearly)
always in state S (sleeping) and thus consuming no CPU, while the new
version using uthreads is continuously in state R (running) and
consuming 2-5% of the CPU. This seems to be an intrinsic consequence
of the userspace-threads or am I wrong here?


Bernd Rinn
Fakultät für Physik
Universität Konstanz

Tel. 07531/88-3812, 
e-mail: Bernd.Rinn at uni-konstanz.de
PGP-Fingerprint: 1F AC 31 64 FF EF A9 67  6E 0D 4C 26 0B E7 ED 5C
Stackless mailing list
Stackless at starship.python.net

More information about the Stackless mailing list