c++

I'm aware of an idiom or pattern for coroutines in C and C++:

struct cofunctor {
    int state = 0;

    void operator () () {
        switch ( state ) {
        case 0: // Caller must initialize to 0

            if ( bar1 ) return;

            while ( bar2 ) {
        state = 1; case 1:

                if ( bar3 ) return;

        state = 2; case 2:

                if ( bar4 ) return;
            }
        state = 3; case 3:
            return;
        }
    }
};

As the function executes, it updates a persistent checkpoint variable. The next time it's called, the value is used to jump into the middle of execution. In practice, the checkpoint would not be only an int but would contain "local" variables.

I'm writing in C++. My use-case seldom yields, so I'd like to update the checkpoints only during exception handling.

Is this pattern known in actual practice, or is it only documented as a curiosity? Does a reusable implementation exist in C++?

(As far as I can tell, Boost.Coroutine uses nonconforming stack hacks, not unlike longjmp multithreading. My application will seldom utilize coroutine control flow, and stack usage may be very high in the numerous "threads," so it is not amenable to such implementation.)


Does a reusable implementation exist in C++?

This article also talks about a one header, stackless implementation that resides inside the Boost.ASIO library.

Another ASIO header seems to indicate that they've gone a step further from the previous state, but I do not know much about this one. It may be the same as the last or not.


I implemented reusable stackful coroutines some time ago in standard C++, which allows you to have local variables (defined as members of coroutine classes). For calling a coroutine (I call it 'fiber' in my implementation) you first initialize a callstack object for containing the state and then start the coroutine. Here's an example how I define a coroutine:

struct fiber_func_test
{ PFC_FIBER_FUNC();
  // locals
  unsigned loop_count;
  // test function
  fiber_func_test(unsigned loops_): loop_count(loops_) {}
  bool tick(fiber_callstack &fc_, ufloat &dt_)
  {
    PFC_FIBER_BODY_BEGIN
    while(loop_count--)
    {
      PFC_FIBER_CALL(fc_, dt_, fiber_func_sleep, (0.3f));
    }
    PFC_FIBER_BODY_END
  }
};

loop_count is a local variable whose state is stored in the stack. And here's how it's called:

fiber_callstack fc;
PFC_FIBER_START(fc, fiber_func_test, (10));
while(fc.tick(0.1f))
  thread_nap();

Here's link to the code: http://sourceforge.net/p/spinxengine/code/HEAD/tree/sxp_src/core/mp/mp_fiber.h

Cheers, Jarkko


Yes it exists, is documented and used in well known and well distributed application (Putty, not C++ though).

  • http://www.chiark.greenend.org.uk/~sgtatham/coroutines.html
  • Another page about this use of Duff's device:

  • http://research.swtch.com/duff
  • Duff even commented on this use saying he used it for interrupt driven state machine (what is now known under the buzz word "Async"):

  • http://brainwagon.org/2005/03/05/coroutines-in-c/
  • 链接地址: http://www.djcxy.com/p/53202.html

    上一篇: 基于状态机(FSM):传入事件

    下一篇: C ++