Continuations and threads (was Re: Iterators & generators)

Tim Peters tim_one at email.msn.com
Sun Feb 20 17:56:37 EST 2000


[Aahz Maruch]
> Okay, now I'm starting to get this (be very, very frightened).  Now,
> can you (or someone) provide an equally simple explanation of the
> differences between continuations and threads?  Given that we already
> have threads (sort of), what is the attraction of continuations?

The latter are more powerful, but that's not really the attraction.
Continuations are both fast and space-efficient compared to threads on most
platforms.  Read Christian's paper!  You'll find, e.g., that his simple
implementation of generators using continuations ran 3x faster than a simple
implementation using threads (& on a platform that does a relatively good
job with threads).  My coroutine-on-threads implementation of some six years
ago was so slow as to be unusable for any real work.  The Stackless
coroutine implementation flies (and see Sam Rushing's writings on Medusa &
friends for deadly practical high-end applications).

> Is it easier to write continuations than simulate threads on an
> unthreaded OS?

I've never seen an implementation of (pseudo)threads using continuations
that I thought was suitable for more than toy researchy problems or
educational purposes.  When it comes to "real work", the pragmatics are
everything.  Threads do very well at the things threads were designed to do
<ahem>.  In particular, the benefit *most* people get from threads in Python
today is simply allowing blocking I/O (or other "system" or "foreign")
operations to proceed in parallel with their Python code, and with each
other.  Since the I/O stuff is coded in vendor C libraries, a Python
implementation of continuations can't get at that benefit at all (random C
code won't let Python "timeslice" it).  So Python threads serve important
purposes Python continuations couldn't touch, and also for which the latter
aren't pragmatically suited.

OTOH, note that backtracking searches, generators, and coroutines (the
things the in crowd <wink> *really* want continuations for) are *not*
pseudo-parallel:  they have a single flow of control, albeit not always
stack-like, and often execute just a few instructions before needing to
"switch".  Threads weren't designed for that; you fight them every step of
the way; and e.g. on some platforms a thread sucks up a megabyte of stack
space, while a continuation will usually suck up only a few hundred bytes.
Now picture Sam trying to juggle ten thousand simultaneous socket
connections, each servicing a possibly different protocol.

There are esoteric variations on continuations designed to deal with "real
parallelism" too, but in Python's role as a glue language it's vital to
speak the same parallelism language all the apps you're pasting together
use.  So real Python has to have real threads no matter what.  So long as
you stay within pure Python, a continuation-based emulation of threads may
be suitable for "educational purposes" on platforms without threads -- but
that's a lot of work to implement, with little bang for the buck.

continuations-suck-but-the-things-you-can-do-with-them-don't-
    and-for-those-things-threads-suck-worse-ly y'rs  - tim






More information about the Python-list mailing list