Boost.Threadにあるpromiseとfutureという2つのクラスは、
スレッド間において安全にデータを読み書きし通知する方法のひとつとして提供されています。
(非同期処理の結果を生成するために使われたりします)
promiseがデータを書き、futureはpromiseによってデータが書かれるまで待機して値を取り出します。
promise::get_future()で待機用のfutureを得ることができるので、そのインスタンスで待機します。
#include <iostream> #include <boost/thread.hpp> #include <boost/ref.hpp> void thread_func(boost::promise<int>& p) { boost::this_thread::sleep(boost::posix_time::seconds(3)); p.set_value(5); // 値を書く } int main() { boost::promise<int> p; boost::unique_future<int> f = p.get_future(); boost::thread t(boost::bind(&thread_func, boost::ref(p))); std::cout << f.get() << std::endl; // 値の準備ができるまで待機して取り出す }
5
promiseとは違い、スレッドで動かす関数の戻り値として値を返すものとして、packaged_taskというのもあります。使い方はほとんど同じです。
#include <iostream> #include <boost/thread.hpp> #include <boost/ref.hpp> int thread_func() { boost::this_thread::sleep(boost::posix_time::seconds(3)); return 5; // 値を返す } int main() { boost::packaged_task<int> pt(thread_func); boost::unique_future<int> f = pt.get_future(); boost::thread task(boost::ref(pt)); std::cout << f.get() << std::endl; // 値の準備ができるまで待機して取り出す }
5
ちなみに、promiseやfutureはvoidで特殊化されていて、これは単純な通知に使用することができます。
#include <iostream> #include <boost/thread.hpp> #include <boost/ref.hpp> void thread_func(boost::promise<void>& p) { boost::this_thread::sleep(boost::posix_time::seconds(3)); p.set_value(); // 通知 } int main() { boost::promise<void> p; boost::unique_future<void> f = p.get_future(); boost::thread t(boost::bind(&thread_func, boost::ref(p))); f.get(); // 通知が来るまで待機 std::cout << "end" << std::endl; }
end