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

futureとpromiseの簡易実装

C++

futureとpromiseは、2つのクラスが共通の状態を参照するというおもしろい作りになっているので、これを自分で作ってみるのはなかなかおもしろいです。
最近のfutureとpromiseはいろいろ機能が足されて、根幹の実装を読み解くのが難しくなってきてるので、簡易的な実装を紹介しておきます。

#include <iostream>
#include <boost/optional.hpp>
#include <boost/shared_ptr.hpp>
 
template <class R>
class shared_state {
    boost::optional<R> value_;
public:
    void set_value(const R& value)
    {
        value_ = value;
    }
 
    bool has_value() const
    {
        return value_.is_initialized();
    }
 
    R get_value() const
    {
        return value_.get();
    }
};
 
template <class R>
class future {
    boost::shared_ptr<shared_state<R>> state_;
public:
    future(boost::shared_ptr<shared_state<R>> state)
        : state_(state) {}
 
    R get()
    {
        while (!state_->has_value()) {}
        return state_->get_value();
    }
};
 
template <class R>
class promise {
    boost::shared_ptr<shared_state<R>> state_;
public:
    promise()
    {
        state_.reset(new shared_state<R>());
    }
 
    future<R> get_future()
    {
        return future<R>(state_);
    }
 
    void set_value(const R& value)
    {
        state_->set_value(value);
    }
};
 
int main()
{
    promise<int> p;
    future<int> f = p.get_future();
 
    p.set_value(3);
 
    int result = f.get();
    std::cout << result << std::endl; // 3
}

本来はこれに、以下のような機能が足されます:

  • mutexとcondition_variableによる、マルチスレッドでの同期
  • exception_ptrによる、あらゆる例外オブジェクトの保持
  • async()関数で指定されたlaunchポリシーの管理(密結合でよろしくない)



宣伝: 『プログラミングの魔導書 Vol.3』 予約受付中です。
http://longgate.co.jp/books/grimoire-vol3.html