タスクは、C++11 標準に追加された最新の機能の 1 つです。スレッドよりも優れた抽象化を提供します。一般的なケースでは、それらを最初に選択する必要があります。
データ チャネルとしてのタスク
タスクはデータ チャネルのように動作します。一方では、送信者が値を設定します。反対側では、レシーバーが値を受け取ります。送信者は promise と呼ばれます 、レシーバー - 未来 .別の言い方をすれば、送信者は、受信者が将来受け取ることができる価値を提供することを約束します。
さらにいくつかの詳細。送信者は、複数の先物に値を提供できます。値の他に、送信者は通知または例外を提供することもできます。 取得 未来の呼び声ブロック .これは、将来の呼び出しが待機する場合、待機する必要があることを意味します promise が値をチャネルに入れるまで。
タスクには 3 つのバリエーションがあります。 std::async による非同期関数呼び出しとして、std::packaged_task による callable の単純なラッパーとして、および std::promise と std::future の明示的なペアとして。
スレッドとタスクの違いを理解する最善の方法は、それらを比較することです。
スレッドとタスク
この小さなコード例は違いを示しています:
int res; std::thread t([&]{res= 3+4;}); t.join(); std::cout << res << std:::endl; auto fut=std::async([]{return 3+4;}); std::cout << fut.get() << std::endl;
子スレッドと promise の両方が 3+4 の合計を計算し、結果を返します。 std::async 呼び出しは、エンドポイント fut と std::async の両方を持つデータ チャネルを生成します。 fut は未来、std::async は約束です。 future は fut.get() の呼び出しで値を取得します。この値は promise によって提供されます。未来は後の時点で行動することができます。
違いは何ですか?
スレッドには
スレッドとタスクの主な違いは、タスクの抽象化レベルが高いことです。タスクはスレッドを自動的に生成しません。正確には、C++ ランタイムがスレッドを作成するかどうかを決定します。決定の理由は次のとおりです。ペイロードの重量はどれくらいですか。使用可能なコア数は?システム負荷はどれくらいですか?
次は?
これが、タスクに関する次の投稿の基礎となりました。次は std::async についてです。(校正者 Alexey Elymanov )