[Python-ideas] asyncore: included batteries don't fit

Trent Nelson trent at snakebite.org
Thu Oct 11 02:55:23 CEST 2012

On Mon, Oct 08, 2012 at 05:13:03PM -0700, Christian Heimes wrote:
> Am 08.10.2012 17:35, schrieb Guido van Rossum:
> > On Mon, Oct 8, 2012 at 5:39 AM, Christian Heimes <christian at python.org> wrote:
> >> Python's standard library doesn't contain in interface to I/O Completion
> >> Ports. I think a common event loop system is a good reason to add IOCP
> >> if somebody is up for the challenge.
> >>
> >> Would you prefer an IOCP wrapper in the stdlib or your own version?
> >> Twisted has its own Cython based wrapper, some other libraries use a
> >> libevent-based solution.
> > 
> > What's an IOCP?
> I/O Completion Ports, http://en.wikipedia.org/wiki/IOCP
> It's a Windows (and apparently also Solaris)

    And AIX, too.  For every OS IOCP implementation, there's a
    corresponding Snakebite box :-)

> API for async IO that can handle multiple threads.

    I find it helps to think of it in terms of a half-sync/half-async
    pattern.  The half-async part handles the I/O; the OS wakes up one
    of your "I/O" threads upon incoming I/O.  The job of such threads
    is really just to pull/push the bytes from/to kernel/user space as
    quickly as it can.

        (Since Vista, Windows has provided a corresponding thread pool
         API that gels really well with IOCP.  Windows will optimally
         manage threads based on incoming I/O; spawning/destroying
         threads as per necessary.  You can even indicate to Windows
         whether your threads will be "compute" or I/O bound, which
         it uses to optimize its scheduling algorithm.)

    The half-sync part is the event-loop part of your app, which simply
    churns away on the data prepared for it by the async threads.

    What would be neat is if the half-async path could be run outside
    the GIL.  They would need to be able to allocate memory that could
    then be "owned" by the GIL-holding half-sync part.

    You could leverage this with kqueue and epoll; have similar threads
    set up to simply process I/O independent of the GIL, using the same
    facilities that would be used by IOCP-processing threads.

    Then the "asyncore" event-loop simply becomes the half-sync part of
    the pattern, enumerating over all the I/O requests queued up for it
    by all the GIL-independent half-async threads.


More information about the Python-ideas mailing list