[Python-ideas] asyncore: included batteries don't fit
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