2011-09-14 14 views
2

コルーチンは、通常、上位レベルの言語で見られるようです。C/C++と呼ばれるコルーチン?

wikipedia/en/wiki/Coroutine

同様にそれらのいくつかの異なる定義があるように思われます。私はルアにあるように、C言語でコルーチンを具体的に呼んでいるのを発見しようとしています。

function foo()  
    print("foo", 1) 
    coroutine.yield() 
    print("foo", 2) 
end 

読み取り、パトリック

+2

あなたの質問は正確に何ですか? –

+0

ありがとうございます。 私は何時間も探しましたが、それは問題です...私は準備が整った何かを探しています。 – Patrick

+0

こんにちはトニーどのようにC/C++のcorountinesを持っている、私は – Patrick

答えて

1

ためのおかげで申し訳ありません - CやC++でもないがコルーチンをサポートしています。しかし、 "C coroutine"の簡単な検索では、次の魅力的な問題に関する論文が得られます。彼の解決策は少ししか実用的ではないかもしれませんが、

+0

ありがとう。 私は何時間も探しましたが、それは問題です...私は準備が整った何かを探しています。 – Patrick

+0

C++ 17にはおそらくコルーチンの実装があります。現在の提案はこちら:https://isocpp.org/files/papers/N3722.pdf – Atifm

2

CまたはC++のコルーチンの言語レベルのサポートはありません。

あなたはアセンブラまたは繊維を使用してそれらを実装できますが、結果はあなたがほぼ確実に例外を使用する能力を失い、クリーンアップのために巻き戻しスタックに頼ることができないだろう++ポータブルおよびCの場合ではないでしょう。

私の意見では、サポートしている言語を使用するか、使用しないかのどちらかを選択する必要があります。自分のバージョンをサポートしていない言語emはトラブルを求めています。ブーストC++ライブラリでの(バージョン1.53.0のような)新しいコルーチンライブラリが

+0

ありがとうございました 私はアセンブリでこれを行うことについて読んでいましたが、例は見つかりませんでした。 ASMで自分のソリューションをローリングすることは自殺になる – Patrick

0

C++用のコルーチンライブラリがたくさんあります。 RethinkDBのHere's one

また、mine header-only libraryもあり、コールバックで使用するように調整されています。私はBoost coroutinesを試しましたが、incompatibility with valgrindのためにまだ使用していません。私の実装はucontext.hを使用しており、これまでvalgrindでうまく動作しています。

"標準"コルーチンでは、コールバックでそれらを使用するためにいくつかのフープを飛び越さなければなりません。

typedef coroutine<void()> coro_t; 
auto lock = make_shared<std::mutex>(); 
coro_t* coro = new coro_t ([handler,buffer,&coro,lock](coro_t::caller_type& ca)->void { 
    p1: ca(); // Pass the control back in order for the `coro` to initialize. 
    coro_t* coro_ = coro; // Obtain a copy of the self-reference in order to call self from callbacks. 
    cherokee_buffer_add (buffer, "hi", 2); handler->sent += 2; 
    lock->lock(); // Prevents the thread from calling the coroutine while it still runs. 
    std::thread later ([coro_,lock]() { 
    //std::this_thread::sleep_for (std::chrono::milliseconds (400)); 
    lock->lock(); // Wait for the coroutine to cede before resuming it. 
    (*coro_)(); // Continue from p2. 
    }); later.detach(); 
    p2: ca(); // Relinquish control to `cherokee_handler_frople_step` (returning ret_eagain). 
    cherokee_buffer_add (buffer, ".", 1); handler->sent += 1; 
}); 
(*coro)(); // Back to p1. 
lock->unlock(); // Now the callback can run. 

、ここでは、それは私にどのように見えるかです:たとえば、ここチェロキーハンドラはブーストコルーチンでどのように見えるかの作業スレッドセーフ(ただし、漏れ)である

struct Coro: public glim::CBCoro<128*1024> { 
    cherokee_handler_frople_t* _handler; cherokee_buffer_t* _buffer; 
    Coro (cherokee_handler_frople_t *handler, cherokee_buffer_t* buffer): _handler (handler), _buffer (buffer) {} 
    virtual ~Coro() {} 
    virtual void run() override { 
    cherokee_buffer_add (_buffer, "hi", 2); _handler->sent += 2; 
    yieldForCallback ([&]() { 
     std::thread later ([this]() { 
     //std::this_thread::sleep_for (std::chrono::milliseconds (400)); 
     invokeFromCallback(); 
     }); later.detach(); 
    }); 
    cherokee_buffer_add_str (_buffer, "."); _handler->sent += 1; 
    } 
}; 
関連する問題