« コルーチン | トップページ | 起動時にQDockWidgetの状態を復元する »

2012年2月 4日 (土)

boost.contextを使ってみました。

以前、setjmp / longjmp関数を使用してコルーチンを実現してみましたが、スタックの関係上、コルーチン内部では、クラスインスタンスが使えないという問題がありました。

今回、boost.contextというものがあるのを知りましたので、試してみました。

以下、ソースになります。

#include <iostream>
#include <string>
#include <boost/context/all.hpp>
using namespace std;
namespace APP {
class CSub {
public:
    void print( int n ) {
        cout << "(" << m_name << ") -> " << n << endl;
    }
public:
    CSub( const string& name )
        : m_name( name )
    { cout << "CSub() : " << m_name << endl; }
    ~CSub() { cout << "~CSub() : " << m_name << endl; }
private:
    string m_name;
};
class CMain {
private:
    static void torampoline( CMain* self ) {
        self->function();
    }
private:
    void yield( void ) {
        m_context.suspend();
    }
    void yield_break( void ) {
        m_complete = true;
        m_context.suspend();
    }
private:
    void function( void ) {
        CSub sub_1( "_1" );
        for( int n=0; n<10; ++n ) {
            sub_1.print( n );
            yield();
        }
        for( int n=0; n<10; ++n ) {
            CSub( "_2" ).print( n );
            if( n != 5 ) {
                yield();
            }
            else {
                yield_break();
            }
        }
    }
public:
    int run( void ) {
        m_context = boost::contexts::context(
            &CMain::torampoline, this,
            boost::contexts::default_stacksize(),
            boost::contexts::no_stack_unwind, boost::contexts::return_to_caller );
        m_complete  = false;
        m_context.start();
        while( !m_complete && !m_context.is_complete() ) {
            m_context.resume();
        }
        if( !m_context.is_complete() ) {
            m_context.unwind_stack();
        }
        return 0;
    }
public:
    CMain() { ; }
    ~CMain() { ; }
private:
    boost::contexts::context m_context;
    bool                     m_complete;
};
}   /* APP */
static APP::CMain g_MainInst;
int main( int argc, char* argv[] ) {
    return g_MainInst.run();
}
実行結果です。
CSub() : _1
(_1) -> 0
(_1) -> 1
(_1) -> 2
(_1) -> 3
(_1) -> 4
(_1) -> 5
(_1) -> 6
(_1) -> 7
(_1) -> 8
(_1) -> 9
CSub() : _2
(_2) -> 0
~CSub() : _2
CSub() : _2
(_2) -> 1
~CSub() : _2
CSub() : _2
(_2) -> 2
~CSub() : _2
CSub() : _2
(_2) -> 3
~CSub() : _2
CSub() : _2
(_2) -> 4
~CSub() : _2
CSub() : _2
(_2) -> 5
~CSub() : _2
~CSub() : _1
すばらしい!!

|

« コルーチン | トップページ | 起動時にQDockWidgetの状態を復元する »

C++」カテゴリの記事

Boost」カテゴリの記事

コメント

コメントを書く



(ウェブ上には掲載しません)




トラックバック


この記事へのトラックバック一覧です: boost.contextを使ってみました。:

« コルーチン | トップページ | 起動時にQDockWidgetの状態を復元する »