ホームページ  >  記事  >  PHPフレームワーク  >  swooleコルーチンの実装原理は何ですか?

swooleコルーチンの実装原理は何ですか?

WBOY
WBOYオリジナル
2022-02-14 17:42:416805ブラウズ

swoole では、Swoole サーバーはデータを受信し、ワーカー プロセスで onReceive コールバックをトリガーしてコルーチンを生成します。Swoole はリクエストごとに対応するコルーチンを作成します。コルーチン内にサブコルーチンも作成できます。コルーチンシングルスレッドなので、同時に動作するコルーチンは 1 つだけです。

swooleコルーチンの実装原理は何ですか?

このチュートリアルの動作環境: Windows10 システム、Swoole4 バージョン、DELL G3 コンピューター

swoole コルーチンの実装原理とは

プロセスとは何ですか?

プロセスはアプリケーションの起動インスタンスです。独立したファイル リソース、データ リソース、およびメモリ空間。

スレッドとは何ですか?

スレッドはプロセスに属し、プログラムの実行者です。プロセスには少なくとも 1 つのメイン スレッドが含まれており、さらに多くの子スレッドを持つこともできます。スレッドには 2 つのスケジューリング戦略があり、1 つはタイムシェアリング スケジューリング、もう 1 つはプリエンプティブ スケジューリングです。

コルーチンとは何ですか?

コルーチンは軽量のスレッドであり、コルーチンもスレッドに属し、コルーチンはスレッド内で実行されます。コルーチンのスケジューリングはユーザーが手動で切り替えるため、ユーザースペーススレッドとも呼ばれます。コルーチンの作成、切り替え、一時停止、破棄はすべてメモリ操作であり、消費量は非常に少なくなります。コルーチンのスケジューリング戦略は、協調スケジューリングです。

Swoole コルーチンの原理

Swoole4 シングルスレッドでマルチプロセスであるため、同じプロセスで同時に実行されるコルーチンは 1 つだけです。 。

Swoole サーバーはデータを受信し、ワーカー プロセスで onReceive コールバックをトリガーし、Ctrip を生成します。 Swoole はリクエストごとに対応する Ctrip を作成します。コルーチン内にサブコルーチンを作成することもできます。

コルーチンの基礎となる実装はシングルスレッドであるため、同時に動作するコルーチンは 1 つだけであり、コルーチンの実行はシリアルです。

そのため、マルチタスクとマルチコルーチンを実行すると、1 つのコルーチンが実行されていると、他のコルーチンは動作を停止します。現在のコルーチンは、ブロッキング IO 操作を実行するとハングし、基礎となるスケジューラーがイベント ループに入ります。 IO 完了イベントが発生すると、基礎となるスケジューラーはイベントに対応するコルーチンの実行を再開します。 。したがって、コルーチンには IO 時間が消費されず、同時実行性の高い IO シナリオに非常に適しています。 (以下に示すように)

swooleコルーチンの実装原理は何ですか?

Swoole のコルーチン実行プロセス

  • コルーチンには IO がなく、待機中です。通常の実行の場合、PHP コードは実行フローの切り替えを引き起こしません

  • コルーチンが IO に遭遇すると、待機し、すぐに制御を切り替えます。IO が完了すると、実行フローは切り替えられます。

  • コルーチンと並列コルーチンは、前のコルーチンと同じロジックで順番に実行されます

  • コルーチンのネストされた実行プロセスIO が発生するまで外側から内側に層ごとに入力され、その後外側のコルーチンに切り替わります。親コルーチンは子コルーチンの終了を待ちません

#コルーチンの実行シーケンス

まず基本的な例を見てみましょう:

go(function () {
    echo "hello go1 \n";});echo "hello main \n";go(function () {
    echo "hello go2 \n";});

go() は \Co::create() の略称で、次の目的で使用されます。コルーチンを作成し、コールバックをパラメータとして受け取ります ここにコールバック内のコードが作成されます コルーチン内で実行されます。

備考: \Swoole\Coroutine は \Co

と省略できます実行結果上記コード:

root@b98940b00a9b /v/w/c/p/swoole# php co.phphello go1
hello main
hello go2

実行結果は普段コードを書いているときと同じ 順番に違いはないようです 実際の実行プロセス:

  • このコードを実行すると、システムは新しいプロセスを開始します

  • go() に遭遇し、現在のプロセスでコルーチンが生成され、コルーチンで heelo go1 が出力され、コルーチンが終了します

  • プロセスはコードの実行を継続し、hello main を出力します。

  • コルーチンを生成し、コルーチン内で heelo go2 を出力し、コルーチンを終了します

このコードを実行すると、システムは新しいプロセスを開始します。この文が理解できない場合は、次のコードを使用できます:

// co.php<?phpsleep(100);

実行して ps aux を使用しますシステム内のプロセスを表示するには:

root@b98940b00a9b /v/w/c/p/swoole# php co.php &⏎
root@b98940b00a9b /v/w/c/p/swoole# ps auxPID   USER     TIME   COMMAND
    1 root       0:00 php -a   10 root       0:00 sh   19 root       0:01 fish  749 root       0:00 php co.php  760 root       0:00 ps aux

少し変更を加えてコルーチンのスケジューリングを体験してみましょう:

use Co;go(function () {
    Co::sleep(1); // 只新增了一行代码
    echo "hello go1 \n";});echo "hello main \n";go(function () {
    echo "hello go2 \n";});
\Co::sleep() 函数功能和 sleep() 差不多, 但是它模拟的是 IO等待(IO后面会细讲). 执行的结果如下:
root@b98940b00a9b /v/w/c/p/swoole# php co.phphello main
hello go2
hello go1

順番に実行されないのはなぜですか?実際の実行プロセス:

    #このコードを実行すると、システムは新しいプロセスを開始します
  • # go() に遭遇し、現在のプロセスでコルーチンが生成されます
  • コルーチンで IO ブロックが発生しました (ここでは、Co::sleep() によってシミュレートされた IO 待機が示されています)。コルーチンは制御を放棄し、コルーチンのスケジューリング キューに入ります。
  • プロセスは続行します。下方向に実行して hello main を出力します
  • #次のコルーチンを実行して hello go2

    # を出力します
  • ##前のコルーチンの準備が完了し、実行を継続して出力しますhello go1

  • この時点で、コルーチンと swoole のプロセスの関係がすでに確認できています。コルーチンのスケジューリングについては、今すぐプログラムを変更しましょう:

    go(function () {
        Co::sleep(1);
        echo "hello go1 \n";});echo "hello main \n";go(function () {
        Co::sleep(1);
        echo "hello go2 \n";});

    出力がどのようなものになるかはすでにご存知だと思います:
  • root@b98940b00a9b /v/w/c/p/swoole# php co.phphello main
    hello go1
    hello go2
推奨学習:

swoole チュートリアル

以上がswooleコルーチンの実装原理は何ですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。