Many-to-Many thread Modelのライブラリを書いてみてる
現在Boost.Contextのmini reviewが実施されてます。これはコルーチンやファイバーを実装するベースとなるコンテキストスイッチを提供します。Boost.CoroutineやBoost.Fiberが頓挫してる中レビューまでこじつけたライブラリです。
既存のBoost.Threadはone-to-one thraed modelを提供し、Boost.Contextはone-to-many thread modelを提供するのでこれを組み合わせてmany-to-manyな物を作ってみました。
Boost.MMM
Boostのnamespaceを使ってるのはその方がコードが楽だからです。まぁそのうち提案出来たら面白いですね。
Boost.Threadのthread::idがboost::hashに対して特殊化されていない、Boost.Containerのflat_mapのiteratorがコンテナの操作に対して安全ではないという問題がありmapを使うという悲しい事態ですがとりあえず動いてるのでよしとしましょう...
例えばこんな感じ
#include <iostream> using namespace std; #include <boost/mmm/scheduler.hpp> #include <boost/mmm/strategy.hpp> #include <boost/mmm/yield.hpp> namespace mmm = boost::mmm; #include <boost/thread/thread.hpp> void f() { using boost::this_thread::get_id; using mmm::detail::current_context::get_current_ctx; for (int i = 0; i < 5; ++i) { cerr << "before: " << get_id() << " => " << get_current_ctx() << endl; mmm::this_ctx::yield(); cerr << "after: " << get_id() << " => " << get_current_ctx() << endl; } } int main() { cerr << "normal call" << endl; f(); cerr << "MMM scheduler" << endl; mmm::scheduler<mmm::strategy::fifo> fifo(10); fifo.add_thread(f); fifo.add_thread(f); fifo.join_all(); }
yieldを含む関数を直接呼んでも問題ない様になってるところが個人的には気に入ってます。
とりあえず実行するユーザースレッドのスケジューリングは現在fifoですが、そのうちいろいろ出来たらいいなーと希望的観測を含めてテンプレートにしてます。スケジューラのctorの引数はカーネルスレッドの数です。
今後はI/O threadを用意してカーネルスレッドをブロックする系のシステムコールなどをうまくpollとかにまとめるようなことが出来たらと思ってます。
まぁそれより先にBoost.Contextが本格的に入らないと...