[Python-ideas] An alternate approach to async IO

Trent Nelson trent at snakebite.org
Wed Nov 28 21:18:19 CET 2012

On Wed, Nov 28, 2012 at 11:57:29AM -0800, Richard Oudkerk wrote:
> On 28/11/2012 7:23pm, Trent Nelson wrote:
> >      Oooer, that's definitely not what I had in mind.  This is how I
> >      envisioned it working (think of events() as similar to poll()):
> >
> >          with aio.events() as events:
> >              for event in events:
> >                  # process event
> >                  ...
> >
> >      That aio.events() call would result in an InterlockedSListFlush,
> >      returning the entire list of available events.  It then does the
> >      conversion into a CPython event type, bundles everything into a
> >      list, then returns.
> >
> >      (In reality, there'd be a bit more glue to handle an empty list
> >       a bit more gracefully, and probably a timeout to aio.events().
> >       Nothing should involve a spinlock though.)
> >
> >          Trent.
> That api is fairly similar to what is in the proactor branch of tulip 
> where you can write
>      for event in proactor.poll(timeout):
>          # process event
> But why use a use a thread pool just to take items from one thread safe 
> (FIFO) queue and put them onto another thread safe (LIFO) queue?

    I'm not sure how "thread pool" got all the focus suddenly.  That's
    just an implementation detail.  The key thing I'm proposing is that
    we reduce the time involved in processing incoming IO requests.

    Let's ignore everything pre-Vista for the sake of example.  From
    Vista onwards, we don't even need to call GetQueuedCompletionStatus,
    we simply tell the new thread pool APIs which C function to invoke
    upon an incoming event.

    This C function should do as little as possible, and should have a
    small a footprint as possible.  So, no calling CPython, no GIL
    acquisition.  It literally just processes completed events, copying
    data where necessary, then doing an interlocked list push of the
    results, then that's it, done.

    Now, on XP, AIX and Solaris, we'd manually have a little thread
    pool, and each thread would wait on GetQueuedCompletionStatus(Ex)
    or port_get().  That's really the only difference; the main method
    body would be identical to what Windows automatically invokes via
    the thread pool approach in Vista onwards.


More information about the Python-ideas mailing list