Settings

Theme

Lua-Style Coroutines in C++

mfichman.blogspot.com

19 points by mfichman 15 years ago · 8 comments

Reader

gorset 15 years ago

Wouldn't "create", "getcurrent" and "switch" be better primitives for coroutines [0]?

Having a concept of caller and callee complicates the maintenance of a large number of "concurrent" coroutines that does different things, and "yield" can be implemented by just using a global variable.

[0]: http://pypy.readthedocs.org/en/latest/stackless.html#corouti...

  • pygy_ 15 years ago

    Lua uses asymmetric coroutines, you're describing the symmetric variety.

    From Programming in Lua[1] by R. Ierusalimschy

    For those that already know something about coroutines, it is important to clarify some concepts before we go on. Lua offers what I call asymmetric coroutines. That means that it has a function to suspend the execution of a coroutine and a different function to resume a suspended coroutine. Some other languages offer symmetric coroutines, where there is only one function to transfer control from any coroutine to another.

    Some people call asymmetric coroutine semi-coroutines (because they are not symmetrical, they are not really co). However, other people use the same term semi-coroutine to denote a restricted implementation of coroutines, where a coroutine can only suspend its execution when it is not inside any auxiliary function, that is, when it has no pending calls in its control stack. In other words, only the main body of such semi-coroutines can yield. A generator in Python is an example of this meaning of semi-coroutines.

    Unlike the difference between symmetric and asymmetric coroutines, the difference between coroutines and generators (as presented in Python) is a deep one; generators are simply not powerful enough to implement several interesting constructions that we can write with true coroutines. Lua offers true, asymmetric coroutines. Those that prefer symmetric coroutines can implement them on top of the asymmetric facilities of Lua. It is an easy task. (Basically, each transfer does a yield followed by a resume.)

    [1] http://www.lua.org/pil/index.html, http://www.lua.org/pil/9.1.html

aliguori 15 years ago

Most C++ implementations throw their hands up at setjmp/longjmp/setcontext/makecontext.

Even if it appears to work, it's a dangerous set of routines to use in C++.

  • pja 15 years ago

    Yeah, this is going to mix very badly with exceptions.

    Also, a little rootling around on the web reveals the following statement in IBM's z/OS docs:

    "Do not issue getcontext() in a C++ constructor or destructor, since the saved context would not be usable in a subsequent setcontext() or swapcontext() after the constructor or destructor returns."

  • mfichmanOP 15 years ago

    Indeed. This was more of an experiment than anything else. Ideally, I should have a function that catches all exceptions before calling the user's function to make it safer.

  • ncarlson 15 years ago

    That's how I've always felt. Coroutines are fun to play with in C++, but I'd never be caught dead using them in production code.

  • gorset 15 years ago

    Do you think they are safer or more dangerous than threads?

Keyboard Shortcuts

j
Next item
k
Previous item
o / Enter
Open selected item
?
Show this help
Esc
Close modal / clear selection