[Python-Dev] Re: [python-coro] coroutines and microthreads

Just van Rossum just@letterror.com
Fri, 17 Nov 2000 14:44:51 +0100


At 7:51 AM -0500 17-11-2000, Guido van Rossum wrote:
[ initialisation ]
>My current solution: for the initial transfer, *no
>argument is allowed*.

In retrospect, that indeed seems the best solution. I wonder why we (as in
the python-coro@egroups clan) didn't think of that before... Glad to have
you here ;-)


[ "main" coro ]
>I've been thinking about names a bit more, and 'main' is a truly lousy
>name.  I now propose a function initial() to get at the main
>coroutine.  (A function out of symmetry with current(), but also
>because in an environment that also supports OS-level threads, there
>is a different main coroutine per OS thread.)

Fine with me.

>> Here's what I did in my own strawman:
>> - resume the guy that resumed me, if any (making it equivalent to suspend())
>
>But there could be a cycle here!  What if A resumed B resumed C
>resumed A?

Here's what I did: if A does suspend(), it resumes C, but at the same time
A _loses_ it's "resumer". So if it does do a suspend() again, it'll resume
the "initial" coro.

>> - if we were resumed by a suspend() call (which in my proposal means we
>> don't have a "resumer", to avoid endless suspend()/suspend() bouncing),
>> resume the "main" coroutine, which is the (non-coro) code that started the
>> first coroutine.
>
>But the main coroutine may not be expecting this -- e.g. in the
>fringe() example, the main coroutine is expecting the next fringe
>item or an EarlyExit exception.

Sure, but you need to be able to go _somewhere_, and this seems more useful
than, say, terminating the app ;-)

[ my own implementiation ]
>> Apart from the initialisation it's pretty much what you propose.
>
>I saw that, and even peeked a bit at it.  It seems you must have
>struggled a bit with the initialization sequence in the squasher
>example, gmcm_coro.py (which BTW is due to Tim Peters in its current
>-- Python -- form).  That's alright -- coroutine initialization *is* a
>problem.

Still, the first-time-no-arguments-allowed rule solves it nicely.

>I've found that finalization is a problem, too: I'm not at all sure
>that my version of that example correctly frees all the coroutines
>when it is done, since several of them are still suspended (waiting
>for more input) when the decision to exit is made.

Are you talking of freeing all data associated with the coroutine, or about
properly finalizing it (so that any finally clauses get executed)? If the
former: don't even try, it's a nightmare with continuations. If the latter:
good question ;-).

>BTW, I've got an almost-working implementation of the coro API using
>Stackless continuations!  Problem: I don't know how to raise an
>exception for a continuation -- which I need to implement EarlyExit.
>Can anyone help?

def hellraiser():
    continuation.return_current()
    raise <whatever>

k = hellraiser()
k.caller = your_co
k()

Just