Future

Future<T>

nine は、nine::concurrent::Future< T > というテンプレートクラスを提供している。 これは、マルチスレッド下での非同期的な結果の受け渡しに用いるための同期オブジェクトである。

Future の概要

クラス定義は次のようになっている:
   template <typename T> class Future
   {
      bool isDone() const;
      bool isCancel() const;

      T get() const;
      T take() const;
      bool set(const T& v);
      bool cancel(const T& v);
   }

Future は要素が一つのキューのようなものである。 結果を渡す側は set() で結果を渡し、受け取る側は get() で受け取る。

get() は set() されるまで同期的に待機する。 isDone() は set() されたかどうかを返す。

Future の使い方

一方のスレッドで待ち受け、もう一方のスレッドでセットする。典型的には次のようになる:
  Future< int > g_future;
  void ProducerFunc() {
    sleep(1000);
    g_future.set(100);
  }
  class main() {
    Thread.start(ProducerFunc());
    int value = g_future.get(); //set されるまで待機
  }

ProduceFunc() を実行するスレッドは、1秒待ってから g_future へ値をセットする。 もう一方のスレッドは main() であり、ProduceFunc スレッドを起動後に直ちに g_future の値を待っている。

このコードでは、main スレッドは get で一旦停止となる。produce スレッドが set した後で再び動き出す。

Future で受け渡されるオブジェクトの生存期間

Future は参照カウンタ式のオブジェクトになっている。 SharedPtr と同様に、複製や代入可能をサポートし、全ての複製された Future が解放された時に実体のオブジェクトも解放されるようになっている。 Future のパラメータ型がポインタの場合には delete が呼ばれるが、非ポイント型の場合は呼ばれない。

get() ではなくて take() で受け取ることもできる。take() を用いた場合、そのオブジェクトの責任は take() した側になる:
  MyClass* p = f.take();
  delete p;