コルーチンとは何ですか?それらは並行性とどのように関連していますか?
コルーチンとは何ですか?それらは並行性とどのように関連していますか?
回答:
コルーチンと並行性はほぼ直交しています。コルーチンは、フロー制御が戻ることなく2つの異なるルーチン間で協調的に渡される一般的な制御構造です。
Pythonの「yield」ステートメントが良い例です。コルーチンを作成します。「yield」が発生すると、関数の現在の状態が保存され、制御は呼び出し元の関数に戻ります。呼び出し元の関数は、実行を譲る関数に戻すことができ、その状態は「降伏」に遭遇したポイントに復元され、実行が続行されます。
Coroutines are a general control structure whereby flow control is cooperatively passed between two different routines without returning.
<-これは同時実行です。あなたが探している言葉は並列性です。
orthogonal = Not similar to each other
?
orthogonal
「お互いに独立している」という意味だと言われました。
以下からのLuaでのプログラミング「Coroutines
セクション」:
コルーチンはスレッド(マルチスレッドの意味で)に似ています。これは、独自のスタック、独自のローカル変数、および独自の命令ポインターを持つ実行行です。しかし、それはグローバル変数と他のコルーチンとほとんど何でも共有します。スレッドとコルーチンの主な違いは、概念的に(または文字通り、マルチプロセッサマシンでは)スレッドを含むプログラムが複数のスレッドを並行して実行することです。一方、コルーチンは協調的です。コルーチンを含むプログラムは常にコルーチンの1つだけを実行しており、この実行中のコルーチンは、明示的に中断するように要求した場合にのみ実行を中断します。
つまり、コルーチンは「協調的」です。マルチコアシステムでも、コルーチンは常に1つしか実行されません(ただし、複数のスレッドを並行して実行できます)。コルーチン間には非プリエンプティブがあり、実行中のコルーチンは実行を明示的に放棄する必要があります。
「concurrency
」については、Rob Pikeのスライドを参照してください。
並行性は、独立して実行される計算の構成です。
したがって、コルーチンAの実行中に、コルーチンBに制御が渡されます。しばらくすると、コルーチンBはコルーチンAに制御を戻します。コルーチン間に依存関係があるため、コルーチンはタンデムで実行する必要があるため、2つのコルーチンは並行性ではありません。
技術的な質問ですが、ほとんどの回答が技術的すぎると思います。コルーチンのプロセスを理解するのに苦労しました。ちょっとわかりますが、同時にはわかりません。
私はここでこの答えが非常に役に立ったと感じました:
https://dev.to/thibmaek/explain-coroutines-like-im-five-2d9
Idan Aryeから引用するには:
あなたのストーリーに基づいて、私はそれをこのようなものにしたいと思います:
あなたは漫画を見始めますが、それはイントロです。イントロを見る代わりに、ゲームに切り替えてオンラインロビーに入ります。ただし、3人のプレーヤーが必要で、あなたとあなたの姉妹だけがそこにいます。他のプレイヤーが参加するのを待つ代わりに、宿題に切り替えて、最初の質問に答えます。2番目の質問には、視聴する必要のあるYouTubeビデオへのリンクがあります。あなたはそれを開きます-そしてそれはロードを開始します。読み込まれるのを待つのではなく、漫画に切り替えます。イントロが終わったので視聴できます。これでコマーシャルができました-一方で、3人目のプレイヤーが参加したので、ゲームに切り替えました。
考えは、タスクを本当に速く切り替えるだけではなく、一度にすべてを実行しているように見せることです。あなたは何かが起こるのを待っている時間(IO)を利用して、あなたの直接の注意を必要とする他のことをします。
確実にリンクを確認してください。私がすべてを引用することはできません。
コルーチンは、サブルーチン/スレッドに似ています。違いは、呼び出し元がサブルーチン/スレッドを呼び出すと、呼び出し元の関数に戻らないことです。ただし、いくつかのコードを実行した後、コルーチンは呼び出し元に戻って、呼び出し元が独自のコードの一部を実行し、コルーチンポイントに戻って実行を停止し、そこから続行することができます。すなわち。コルーチンには複数の入口と出口があります
基本的に、コルーチンには2つのタイプがあります。
Kotlinはスタックレスコルーチンを実装しています。つまり、コルーチンには独自のスタックがないため、ネイティブスレッドにマップされません。
これらはコルーチンを開始する関数です:
launch{}
async{}
あなたはここからもっと学ぶことができます:
https://www.kotlindevelopment.com/deep-dive-coroutines/
https://blog.mindorks.com/what-are-coroutines-in-kotlin-bf4fecd476e9
Pythonコルーチンから:
Pythonコルーチンの実行は、多くの時点で一時停止および再開できます(コルーチンを参照)。コルーチン関数の本体内で、awaitおよびasync識別子は予約済みキーワードになります。await式、async forおよびasync withは、コルーチン関数本体でのみ使用できます。
コルーチンは、実行を一時停止して 後で再開できる機能です。コルーチンはスタックレスです。呼び出し側に戻って実行を一時停止します。これにより、非同期で実行されるシーケンシャルコードが可能になり(明示的なコールバックなしで非ブロッキングI / Oを処理するなど)、遅延計算された無限シーケンスやその他の使用に関するアルゴリズムもサポートされます。
他の人の答えと比較してください:
私の意見では、再開された後の部分は、@ Twinkleと同様に、コアの違いです。
ドキュメントの多くのフィールドはまだ進行中ですが、この部分は@Nan Xiaoを除いてほとんどの回答と似ています
一方、コルーチンは協調的です。コルーチンを含むプログラムは常にコルーチンの1つだけを実行しており、この実行中のコルーチンは、明示的に中断するように要求した場合にのみ実行を中断します。
LuaのProgramから引用されているため、多分それは言語に関連している(現時点ではLuaに精通していない)、すべてのドキュメントが1つの部分のみについて言及しているわけではありません。
コンカレントとの関係:コルーチン(C ++ 20)の
「実行」部分があります。ここで引用するには長すぎます。
詳細の他に、いくつかの状態があります。
When a coroutine begins execution
When a coroutine reaches a suspension point
When a coroutine reaches the co_return statement
If the coroutine ends with an uncaught exception
When the coroutine state is destroyed either because it terminated via co_return or uncaught exception, or because it was destroyed via its handle
@ user217714の回答の下の@Adam Aroldからのコメントとして。それは並行性です。
しかし、それはマルチスレッドとは異なります。
std :: threadから
スレッドを使用すると、複数の関数を同時に実行できます。スレッドは、関連するスレッドオブジェクトが構築されるとすぐに実行を開始し(OSスケジューリング遅延が保留中)、コンストラクター引数として提供されるトップレベルの関数から始まります。トップレベル関数の戻り値は無視され、例外がスローされて終了した場合は、std :: terminateが呼び出されます。トップレベル関数は、std :: promiseを介して、または共有変数を変更することによって、戻り値または例外を呼び出し元に通知する場合があります(同期が必要な場合があります。std:: mutexおよびstd :: atomicを参照してください)。
並行性であるため、特に(OSの観点から)待機が避けられない場合はマルチスレッドのように機能し、それが混乱を招く理由でもあります。
コルーチンは特別な種類のサブプログラムです。従来のサブプログラムに存在する、呼び出し元と呼び出されたサブプログラム間のマスタースレーブ関係ではなく、呼び出し元と呼び出されたコルーチンはより公平です。
コルーチンは、複数のエントリを持ち、それら自体を制御するサブプログラムです。Luaで直接サポートされています
対称制御とも呼ばれます:呼び出し元と呼び出されたコルーチンはより同等に基づいています
コルーチンの呼び出しは履歴書と呼ばれます
コルーチンの最初の再開は最初ですが、後続の呼び出しは、コルーチンで最後に実行されたステートメントの直後の時点で開始されます
コルーチンは繰り返し、おそらくは永遠に互いに再開します
コルーチンは、プログラム単位(コルーチン)の準並行実行を提供します。それらの実行はインターリーブされますが、オーバーラップされません
このリンクからの説明は非常に簡単です。これらの回答はいずれも、この回答の最後の箇条書きを除いて、同時実行性と並列性を説明するものではありません。
伝説的なジョーアームストロングによる「プログラミングアーラン」からの引用:
並行プログラムは、並列コンピューター上で潜在的に高速に実行できます。
並行プログラムは、並行プログラミング言語で書かれたプログラムです。パフォーマンス、スケーラビリティ、またはフォールトトレランスの理由から、並行プログラムを作成します。
並行プログラミング言語は、並行プログラムを作成するための明示的な言語構造を持つ言語です。これらの構成要素はプログラミング言語の不可欠な部分であり、すべてのオペレーティングシステムで同じように動作します。
並列コンピューターは、同時に実行できる複数の処理ユニット(CPUまたはコア)を持つコンピューターです。
したがって、並行性は並列処理と同じではありません。シングルコアコンピューターで並行プログラムを作成することもできます。タイムシェアリングスケジューラは、プログラムが同時に実行されていると感じさせます。
並行プログラムは、並列コンピューターで並列に実行される可能性がありますが、保証されていません。OSは、プログラムを実行するためのコアを1つだけ提供する場合があります。
したがって、並行性は並行プログラムのソフトウェアモデルであり、プログラムが物理的に並列実行できることを意味しません。
「コルーチン」という単語は、「co」(協調的)と「ルーチン」(関数)の2つの単語で構成されています。
a。それは並行性または並列性を実現しますか?
簡単にするために、シングルコアコンピュータでそれを説明しましょう。
並行性は、OSからのタイムシェアリングによって実現されます。スレッドは、CPUコアの割り当てられたタイムフレームでコードを実行します。OSによってプリエンプトできます。また、OSを制御する可能性もあります。
一方、コルーチンは、OSではなく、スレッド内の別のコルーチンに制御を渡します。したがって、スレッド内のすべてのコルーチンは、OSが管理する他のスレッドにCPUコアを譲らずに、そのスレッドのタイムフレームを利用します。
したがって、コルーチンは、OS(または準並列処理)ではなく、ユーザーがタイムシェアを実現すると考えることができます。コルーチンは、それらのコルーチンを実行するスレッドに割り当てられた同じコアで実行されます。
コルーチンは並列処理を実現しますか?CPUにバインドされたコードの場合、違います。タイムシェアのように、それらは並列に実行されているように感じますが、それらの実行はオーバーラップされずにインターリーブされます。IOバウンドの場合、はい、コードではなくハードウェア(IOデバイス)によって並列処理を実現します。
b。関数呼び出しとの違いは?
写真が示すように、return
コントロールを切り替えるために呼び出す必要はありません。それなしで譲ることができreturn
ます。コルーチンは、現在の関数フレーム(スタック)の状態を保存して共有します。したがって、の際に呼び出しスタックをスタックして巻き戻すためにレジスタとローカル変数を保存する必要がないため、関数よりもはるかに軽量ですcall ret
。
@ user21714の答えを詳しく説明します。コルーチンは、同時に実行できない独立した実行パスです。これらは、python
これらのパス間の切り替えを処理するために、コントローラー(コントローラーライブラリなど)に依存しています。しかし、これが機能するためには、コルーチン自体がyield
、実行を一時停止できるようにする呼び出しまたは同様の構造を実行する必要があります。
代わりに、スレッドは独立したコンピューティングリソース上で実行され、互いに並行して実行されます。それらは異なるリソース上にあるため、yieldを呼び出して他の実行パスを続行できるようにする必要はありません。
あなたはmultihreadedプログラムを起動することによってこの効果を見ることができます-例えばjvm
アプリケーション-あなたの全8れるcore i7
ハイパースレッドコアが利用されている:あなたは797%の使用率が表示されることがありますActivity Monitor
かTop
。代わりに、典型的なpython
プログラムを実行しているとき- coroutines
またはpython threading
-を使用している場合でも、使用率は100%で最大になります。つまり、1つのマシンのハイパースレッドです。