BT

InfoQ ホームページ ニュース 堅牢で強力なFeatureをC++11で実現するFacebook Folly Feature

堅牢で強力なFeatureをC++11で実現するFacebook Folly Feature

ブックマーク

原文(投稿日:2015/07/13)へのリンク

Facebookは先頃,Folly Futureという,既存のstd::futureを機能拡張するC++11ライブラリを導入した

Futureは並列操作の同期に使用される構成要素である。最初は値の分からない非同期演算の結果を参照する,読み取り専用のプロキシオブジェクトがFutureだ。まだ完了(fulfill)していないFutureの値をクライアントが読み出そうとすると,そのクライアントはブロックされる。ひとつのFutureは通常,ひとつのPromiseに関連付けられている。Futureの値への書き込みアクセスを提供するのがPromiseだ。

以下のコードで示すような非同期操作では,ブロックされることなく,読み取り専用のFutureをすぐに返すことが可能だ。

#include <folly/futures/Future.h> 
using folly::Future;

Future<Output> asyncOperation(Input);
Future<Output> f = asyncOperation(input);

asyncOperationは非同期呼び出しのラッパである。 クライアントは次にFutureにアクセスして,関連するPromiseisReady()メソッドを使って完了しているかチェックした上で,value()を使ってその値を取得する。

Futureはその関連するPromiseから生成されて,setValue()setWith()のいずれかを使って値を設定することができる。

using folly::Promise;

Future<double> getEnergy(int year) {
  auto promise = make_shared<Promise<double>>();

  std::thread([=]{
    promise->setWith(std::bind(getEnergySync, year));
  }).detach();
  
  return promise->getFuture();
}

Folly Futuresが本領を発揮するのはFuture::thenメソッドを使うときだ。コールバックの連鎖が簡単に実現可能であるため,コールバック地獄を防止できる。チェーンがどのように動作するのかを以下に示す。

Future<OutputA> futureA(Output);
Future<OutputB> futureB(OutputA);
Future<OutputC> futureC(OutputB);

OutputD d(OutputC) {
  if (somethingExceptional) throw anException;
  return OutputD();
}

Future<double> fut =
  fooFuture(input)
  .then(futureA)
  .then(futureB)
  .then(futureC)
  .then(d)
  .then([](OutputD outputD) { // lambdas are ok too
    return outputD * M_PI;
  });

Folly Futuresの提供する,もうひとつの強力なビルディングブロックがcollectメソッドだ。Futureのコレクションを,すべてのFutureの完了によって完了状態になる単一のFutureとして扱うことができる。collertと同じように,次の機能も提供されている。

  • collectAny: 入力のFutureのいずれかの完了によって完了する。
  • collectN: N個のFutureが完了するまで待機する。
  • map: Futureのコレクションと関数を設定し,各入力Futureのthen()に対してその関数をコールする。Futureの別の配列を返す。
  • reduce: Futureのコレクション以外に2つの引数関数(換算値と換算シーケンスの次の値)を取って,それぞれのFutureにその関数を適用する。

最後に,Folly Futuresでは,コールバックの実行時に実行コンテキストの概念もサポートされている。executorオブジェクトをthenに渡して,そのコールバックをexecutor経由で行うようなことも可能だ。

struct Executor {
  using Func = std::function<void()>;
  virtual void add(Func) = 0;
};

a(input).then(executor, b);

Folly Futureの詳しい情報は,資料で見ることができる。

この記事に星をつける

おすすめ度
スタイル

こんにちは

コメントするには InfoQアカウントの登録 または が必要です。InfoQ に登録するとさまざまなことができます。

アカウント登録をしてInfoQをお楽しみください。

HTML: a,b,br,blockquote,i,li,pre,u,ul,p

コミュニティコメント

  • 誤植

    by kom low /

    スパムの可能性があると認識されました。モデレーターが確認し問題がなければ24時間以内に公開します。その際あなたへの通知は行われませんのでご了承ください。

    タイトルの"Feature"は原文では"Future"です。

HTML: a,b,br,blockquote,i,li,pre,u,ul,p

HTML: a,b,br,blockquote,i,li,pre,u,ul,p

BT

あなたのプロファイルは最新ですか?プロフィールを確認してアップデートしてください。

Eメールを変更すると確認のメールが配信されます。

会社名:
役職:
組織規模:
国:
都道府県:
新しいメールアドレスに確認用のメールを送信します。このポップアップ画面は自動的に閉じられます。