ホームページ >バックエンド開発 >PHPチュートリアル >phpコルーチンの詳しい説明(例付き)
この記事では、PHP コルーチンの詳細な説明 (例付き) を提供します。一定の参考価値があります。必要な友人が参照できます。お役に立てれば幸いです。
コルーチンについて話す前に、マルチプロセス、マルチスレッド、並列性、および同時性について話しましょう。
シングルコア プロセッサの場合、マルチプロセス マルチタスクの原理は、オペレーティング システムが毎回特定の CPU タイム スライスをタスクに割り当て、その後割り込み、次のタスクに特定のタイム スライスを実行させることです。そしてまた中断し、次の作業に進む、というように続きます。
実行タスクの切り替えが非常に速いため、外部ユーザーには複数のタスクが同時に実行されているような印象を与えます。
マルチプロセスのスケジューリングは、オペレーティング システムによって実装されます。プロセス自体は、いつスケジュールされるかを制御できません。つまり、プロセスのスケジューリング
は、外部の # によって実行されます。 ## スケジューラ プリエンプティブ 実装
プリエンプティブマルチタスクの正反対であり、プリエンプティブ マルチタスクのスケジューラは、自身の希望に関係なく、実行中のタスクを強制的に中断できます。プログラムが自動的に制御を引き継ぐだけであれば、悪意のあるプログラムが他のタスクと共有せずにすべての CPU 時間を簡単に占有してしまうでしょう。
積極的に制御を外部スケジューラーに放棄しますxrange 関数を実装するジェネレーターの例に戻ります。実行プロセス全体の切り替えは、次の図で表すことができます。
コルーチンは、
純粋なユーザーモード スレッドとして理解でき、むしろ コラボレーション
を通じてタスクの切り替えを実行します。先取りよりも。 プロセスやスレッドと比較すると、コルーチンのすべての操作はオペレーティング システムのカーネル モードではなくユーザー モードで完了でき、作成と切り替えのコストが非常に低くなります。
簡単に言えば、
Coroutine は、現在のタスクの実行を中断し、現在のローカル変数を保存し、次回実行を継続するために現在のローカル変数を復元するメソッドを提供することです。 大きなタスクを複数の小さなタスクに分割し、順番に実行できます。システム IO を待機している小さなタスクがある場合は、それをスキップして次の小さなタスクを実行します。このようにして、スケジュールを戻すことができます。オペレーションと CPU 計算の並列実行により、一般にタスクの実行効率が向上します。これがコルーチンの意味です。
マルチスレッド
単一コアの下では、マルチスレッドを実行する必要があります。 concurrent;ただし、統合プロセスの現在のマルチスレッドはマルチコア CPU で実行できるため、並列処理が可能です。
Concurrency (並行性)
Parallel (Parallesim)
並列処理と同時実行の違い
はプログラムの構造を指し、並列
はプログラムの状態を指します。 runningParallel
は同時実行である必要があります。Parallel
は 同時実行
設計の一種です 単一のスレッドが
Parallel## に到達することはできません# stateCoroutine
これにより、ジェネレーターから呼び出し元への一方向通信が、両者の間の双方向通信に変更されます。send メソッドについては前の記事ですでに説明しました。コルーチンについて理解しましょう
同期コード
function printNum($max, $caller) { for ($i=0; $i<$max; $i++ ) { echo "调度者:" . $caller . " 打印:" . $i . PHP_EOL; } } printNum(3, "caller1"); printNum(3, "caller2"); # output 调度者:caller1 打印:0 调度者:caller1 打印:1 调度者:caller1 打印:2 调度者:caller2 打印:0 调度者:caller2 打印:1 调度者:caller2 打印:2
# 本代码手动调整了进程执行代码的顺序,当然本代码实现不用协程也可以,只是利用本流程说明协程作用 # 生成器给了我们函数中断,协程[生成器send]给了我们重新唤起生成器函数的能力 function printNumWithGen($max) { for ($i=0; $i<$max; $i++ ) { $res = yield $i; echo $res; } } $gen1 = printNumWithGen(3); $gen2 = printNumWithGen(3); // 手动执行caller1 再 caller2 $gen1->send("调度者: caller1 打印:" . $gen1->current() . PHP_EOL); $gen2->send("调度者: caller2 打印:" . $gen2->current() . PHP_EOL); // 手动执行caller1 再 caller2 $gen1->send("调度者: caller1 打印:" . $gen1->current() . PHP_EOL); $gen2->send("调度者: caller2 打印:" . $gen2->current() . PHP_EOL); // 手动执行caller2 再 caller1 $gen2->send("调度者: caller2 打印:" . $gen2->current() . PHP_EOL); $gen1->send("调度者: caller1 打印:" . $gen1->current() . PHP_EOL); # output 调度者: caller1 打印:0 调度者: caller2 打印:0 调度者: caller1 打印:1 调度者: caller2 打印:1 调度者: caller2 打印:2 调度者: caller1 打印:2
以上がphpコルーチンの詳しい説明(例付き)の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。