[解決済み] C++20のコルーチンとは何ですか?
質問
のコルーチンとは何ですか? c++20 ?
並列処理2」や「並列処理2」とどのように違うのでしょうか?
下の画像はISOCPPのものです。
https://isocpp.org/files/img/wg21-timeline-2017-03.png
どのように解決するのですか?
抽象的なレベルでは、コルーチンは、実行のスレッドを持つという考えから、実行状態を持つという考えを分割します。
SIMD (single instruction multiple data) は複数の実行スレッドを持ちますが、実行状態は1つだけです (複数のデータで動作するだけです)。 おそらく並列アルゴリズムはこれに似ていて、異なるデータに対して1つのプログラム(quot)を実行させます。
スレッドには、複数の実行スレッドと複数の実行状態があります。 複数のプログラム、複数の実行スレッドがあるのです。
コルーチンは複数の実行状態を持ちますが、実行のスレッドを持ちません。 プログラムを持っていて、プログラムは状態を持ちますが、実行スレッドを持ちません。
コルーチンの最も簡単な例は、他の言語からのジェネレータや列挙体です。
擬似コードで
function Generator() {
for (i = 0 to 100)
produce i
}
は
Generator
が呼び出され、最初に呼び出されたときには
0
. その状態は記憶され(どの程度の状態かはコルーチンの実装によって異なる)、次に呼ばれたときには、それが去ったところから続けられる。 だから、次に呼ばれたときには1が返される。 次に2が返される。
最後にループの終わりに到達し、関数の終わりから落ちます;コルーチンは終了します。 (ここで何が起こるかは言語によって異なりますが、pythonでは例外を投げます)。
コルーチンはC++にこの機能をもたらします。
コルーチンには、スタックフルとスタックレスの2種類があります。
スタックレスコルーチンは、その状態と実行場所のローカル変数のみを保存します。
スタックフルコルーチンは、スタック全体を格納します(スレッドのようなもの)。
スタックレスコルーチンは非常に軽量にすることができます。 私が読んだ最後の提案は、基本的にあなたの関数をラムダのようなものに書き換えることを含んでいました。すべてのローカル変数はオブジェクトの状態に入り、ラベルはコルーチンが中間結果を生成する場所への/からのジャンプに使用されます。
コルーチンは協調的マルチスレッドに似ているため、値を生成するプロセスをquot;yield"と呼び、実行ポイントを呼び出し側に返すことになります。
Boostにはスタックフルコルーチンの実装があり、yieldするための関数を呼び出すことができます。 スタックフルコルーチンはより強力ですが、より高価でもあります。
コルーチンには単純なジェネレータ以上のものがあります。 コルーチンの中でコルーチンを待ち受けることができるので、便利な方法でコルーチンを構成することができます。
コルーチンは、if、ループ、関数呼び出しと同様に、(ステートマシンのような)特定の有用なパターンをより自然な方法で表現できる、別の種類の"構造化goto"である。
C++におけるコルーチンの具体的な実装は、少し興味深いものです。
最も基本的なレベルでは、C++にいくつかのキーワードを追加しています。
co_return
co_await
co_yield
と、それらと連携するいくつかのライブラリタイプがあります。
関数は、その本体にコルーチンの1つを持つことによって、コルーチンになります。 そのため、宣言上は関数と見分けがつかない。
これら 3 つのキーワードのいずれかが関数本体で使用されると、戻り値の型と引数の標準的な検査が行われ、関数はコルーチンに変換されます。 この検査は、関数が中断されたときに関数の状態をどこに保存するかをコンパイラに知らせます。
最も単純なコルーチンはジェネレータです。
generator<int> get_integers( int start=0, int step=1 ) {
for (int current=start; true; current+= step)
co_yield current;
}
co_yield
は関数の実行を一時停止し、その状態を
generator<int>
に格納し、その後
current
を通して
generator<int>
.
返された整数をループすることができます。
co_await
は、あるコルーチンを別のコルーチンに継ぎ足すことができます。 もし、あるコルーチンの中にいて、先に進む前に待機しているもの(多くの場合、コルーチン)の結果が必要な場合は
co_await
を実行する。 もしそれが準備できていれば、すぐに実行し、そうでなければ、待機しているものが準備できるまで中断します。
std::future<std::expected<std::string>> load_data( std::string resource )
{
auto handle = co_await open_resouce(resource);
while( auto line = co_await read_line(handle)) {
if (std::optional<std::string> r = parse_data_from_line( line ))
co_return *r;
}
co_return std::unexpected( resource_lacks_data(resource) );
}
load_data
を生成するコルーチンです。
std::future
を生成するコルーチンです。
open_resource
そして
read_line
は、おそらくファイルを開いてそこから行を読み出す非同期コルーチンです。 その
co_await
のサスペンドとレディ状態を結びつけています。
load_data
のサスペンドとレディ状態をその進捗に結びつける。
C++のコルーチンは、ユーザースペースの型の上に最小限の言語機能のセットとして実装されたため、これよりもはるかに柔軟です。 ユーザースペースの型は、効果的に
co_return
co_await
と
co_yield
というのは
-- モナドの省略可能な式を実装するために、これを使う人を見たことがあります。
co_await
が自動的に外側のオプショナルに空の状態をプロポゲートするようなモナドオプショナル式を実装しているのを見ました。
modified_optional<int> add( modified_optional<int> a, modified_optional<int> b ) {
co_return (co_await a) + (co_await b);
}
の代わりに
std::optional<int> add( std::optional<int> a, std::optional<int> b ) {
if (!a) return std::nullopt;
if (!b) return std::nullopt;
return *a + *b;
}
関連
-
[解決済み】変数 '' を抽象型 '' と宣言できない。
-
[解決済み】クラステンプレートの使用にはテンプレート引数リストが必要です
-
[解決済み】エラー:不完全な型へのメンバーアクセス:前方宣言の
-
[解決済み] [Solved] インクルードファイルが開けません。'stdio.h' - Visual Studio Community 2017 - C++ Error
-
[解決済み】なぜ、サイズ8の初期化されていない値を使用するのでしょうか?
-
[解決済み] explicit キーワードの意味は?
-
[解決済み] ルール・オブ・スリーとは?
-
[解決済み] C++で仮想関数が必要な理由とは?
-
[解決済み】C/C++の"-->"演算子とは何ですか?
-
[解決済み】画像処理。コカ・コーラ缶」認識のためのアルゴリズム改良
最新
-
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 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み】Visual Studio 2015で「非標準の構文; '&'を使用してメンバーへのポインターを作成します」エラー
-
[解決済み】 != と =! の違いと例(C++の場合)
-
[解決済み】IntelliSense:オブジェクトに、メンバー関数と互換性のない型修飾子がある
-
[解決済み】'cout'は型名ではない
-
[解決済み] 非常に基本的なC++プログラムの問題 - バイナリ式への無効なオペランド
-
[解決済み】fpermissiveフラグは何をするのですか?
-
[解決済み】リンカーエラーです。"リンカ入力ファイルはリンクが行われていないため未使用"、そのファイル内の関数への未定義参照
-
[解決済み】浮動小数点数の乱数生成
-
[解決済み】Visual Studioのデバッガーエラー。プログラムを開始できません 指定されたファイルが見つかりません
-
[解決済み】警告 - 符号付き整数式と符号なし整数式の比較