[解決済み] 未来と約束
2022-05-09 08:16:46
質問
未来と約束の違いに戸惑いを感じています。
明らかにメソッドなどが違うのですが、実際の使用例はどうなのでしょうか?
そうなんですか?
- 非同期タスクの管理をしているときに、future を使って "in future" の値を取得しています。
- 非同期タスクの場合、プロミスを戻り値として使用し、ユーザーがプロミスから未来を取得できるようにします。
解決方法は?
FutureとPromiseは、非同期操作の2つの側面です。
std::promise
は、非同期操作の "プロデューサー/ライター" が使用します。
std::future
は、非同期操作のコンシューマー/リーダーで使用されます。
このように2つの別々の"interface"に分かれているのは、以下の理由からです。 隠す 書き込み/設定/quot; 機能を消費者/読者/quot; から分離することができます。
auto promise = std::promise<std::string>();
auto producer = std::thread([&]
{
promise.set_value("Hello World");
});
auto future = promise.get_future();
auto consumer = std::thread([&]
{
std::cout << future.get();
});
producer.join();
consumer.join();
std::promise を使って std::async を実装する一つの(不完全な)方法として、以下のようなものが考えられます。
template<typename F>
auto async(F&& func) -> std::future<decltype(func())>
{
typedef decltype(func()) result_type;
auto promise = std::promise<result_type>();
auto future = promise.get_future();
std::thread(std::bind([=](std::promise<result_type>& promise)
{
try
{
promise.set_value(func()); // Note: Will not work with std::promise<void>. Needs some meta-template programming which is out of scope for this question.
}
catch(...)
{
promise.set_exception(std::current_exception());
}
}, std::move(promise))).detach();
return std::move(future);
}
使用方法
std::packaged_task
これは、ヘルパーです (つまり、基本的には上でやっていたことを実行します)。
std::promise
のようにすれば、より完全で、より高速になる可能性があります。
template<typename F>
auto async(F&& func) -> std::future<decltype(func())>
{
auto task = std::packaged_task<decltype(func())()>(std::forward<F>(func));
auto future = task.get_future();
std::thread(std::move(task)).detach();
return std::move(future);
}
とは若干異なることに注意してください。
std::async
ここで、返された
std::future
は、破壊されたとき、スレッドが終了するまで実際にブロックされます。
関連
-
[解決済み] クラスにデフォルトコンストラクタが存在しない。
-
[解決済み】デバッグアサーションに失敗しました
-
[解決済み] jQueryのディファレンシャルとプロミス - .then() vs .done()
-
[解決済み] 既存のコールバックAPIをプロミスに変換するにはどうすればよいですか?
-
[解決済み] プロミスは単なるコールバックではないのか?
-
[解決済み】画像処理。コカ・コーラ缶」認識のためのアルゴリズム改良
-
[解決済み】PromiseとObservablesの違いは何ですか?
-
[解決済み] Intel CPU の _mm_popcnt_u64 で、32 ビットのループカウンターを 64 ビットに置き換えると、パフォーマンスが著しく低下します。
-
[解決済み] Angular HttpPromise: `success`/`error` メソッドと `then` の引数の違い。
-
[解決済み】JavaScriptのプロミス - reject vs. throw
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み】C++でint型に無限大を設定する
-
[解決済み] error: 'ostream' does not name a type.
-
[解決済み】C++でランダムな2倍数を生成する
-
[解決済み】Cygwin Make bash コマンドが見つかりません。
-
[解決済み】'cout'は型名ではない
-
[解決済み】エラー。switchステートメントでcaseラベルにジャンプする
-
[解決済み】オブジェクト引数のない非静的メンバ関数の呼び出し コンパイラーエラー
-
[解決済み】#include<iostream>は存在するのですが、「識別子 "cout "は未定義です」というエラーが出ます。なぜですか?
-
[解決済み】浮動小数点数の乱数生成
-
[解決済み] std::promiseとは何ですか?