読者です 読者をやめる 読者になる 読者になる

Boost.Thread promiseとfuture

C++

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