話題のSleep sortのGo言語版(Big Sky :: Sleep sort in Go)を見かけたので、Visual C++ 2010のAsynchronous Agents Libraryで書き直してみました。「完全に一致」感をお楽しみください。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | #include <agents.h> int main(int argc, char **argv) { using namespace Concurrency; using Concurrency::receive; auto args = boost::make_iterator_range(&argv[1], &argv[argc]); unbounded_buffer<std::int64_t> done; BOOST_FOREACH(auto arg, args) { auto i = boost::lexical_cast<std::int64_t>(arg); //go(std::bind([&](std::int64_t i) { // Sleep(i * 1000); // asend(done, i); //}, i));* go([&, i]() { Sleep(i * 1000); asend(done, i); }); } BOOST_FOREACH(auto arg, args) { std::cout << receive(done) << std::endl; }; } |
上のコード内、go関数(後述)の呼出はコメントアウトしたものとそうでないもの2つ書いてあります。コメントアウトしているほうがGo言語版の元のコードに忠実なのですが、VC++ 2010のbindはラムダ式に対して使うとエラーになるので、もう1つの書き方(ラムダ式でのキャプチャ)を用意しました。
前回、threadクラスをnewしたまま放置していたことを反省し、今回はスレッドプールで実行するようにしました。それが今回作ったgo関数です。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | typedef std::function<void ()> thread_func; DWORD CALLBACK goRunner(void* p) { std::unique_ptr<thread_func> pf(static_cast<thread_func*>(p)); (*pf)(); return 0; } void go(thread_func f) { std::unique_ptr<thread_func> pf(new thread_func(std::move(f))); if (QueueUserWorkItem(goRunner, pf.get(), WT_EXECUTEDEFAULT)) { pf.release(); } } |
完全なソースコードはこちらからどうぞ: sleep_sort_ag.cpp。
スポンサード リンク |
この記事のカテゴリ
- VC++ ⇒ Sleep sortをVC++ 2010のAsynchronous Agents Libraryで