1.コルティンの「ブロッキング」とスレッドの「非ブロッキング」
スレッド内のすべてのcoroutineは、前の章のコードで、基本的にシリアルに実行されます:https://blog.csdn.net/qq_44065088/article/details/109272505
Producer coroutine関数では、poll関数が呼び出されて1秒間待機し、co_cond_timedwait関数も呼び出されてConsumerのプロデューサー信号を待機していることがわかります。コルーチンの観点からは、これらの待機は同期(同期)およびブロッキング(ブロッキング)のように見えますが、基になるスレッドの観点からは、非ブロッキング(非ブロッキング)であることに注意してください。 例:スレッドのプロデューサー-コンシューマーモデルから、pthread_cond_waitもスレッドをブロックします。スレッドの観点からは、スレッドはブロックされているように見えますが、カーネルの観点からは、それ自体はブロックされません。カーネルは、他のスレッドの実行を急いでスケジュールしてください。同じ理由:コロチンは同じです。コルーチン自体の場合、ブロッキングが実現されますが、以下のスレッドの場合、他のコルーチン機能の実行でビジー状態になる可能性があります。
カーネルのブロッキングを回避するには、カーネルが提供する非ブロッキングIOメカニズムに依存し、fcntlを使用してソケットファイル記述子をnonBlockに設定する必要があります。もちろん、libcoも非常に配慮されています。これは、このnonBlockプロセスをカプセル化し、「同期ブロッキング」のふりをします。 (co_cond_timedwait()と同じ)。実際、go languageはこれを行いますが、libcoの偽装はより徹底的で欺瞞的であるため、目が私たちを欺くことがよくあります。Libcoはdlsymメカニズムを介してさまざまなネットワークIO関連のシステム呼び出しをフックし、ユーザーが「同期」できるようにします。""メソッドは、読み取り、書き込み、接続などの関数を直接使用するため、co_enable_hook_sys()がプロデューサーコンシューマーcoroutine関数で呼び出されていることがわかります。 [フックシステム呼び出し関数は、呼び出し後にオンになり、実装にはファイル記述子をnoblockに設定します。そうしないと、スレッドブロッキングに分類されます]
プロセスについて簡単に説明します。ソケット接続がある場合は、最初に非ブロッキングに設定してから、coroutineを開始してリンクを処理し、coroutineがreadを呼び出して、この新しい接続からの読み取りを試みます。データ、この時点で呼び出された読み取りはフックオフされているため、目で騙されないでください。4つ機能します。
- 1.この読み取り(偽のMonkey King)は、現在のコルルーチンをタイマーに登録して、将来の読み取りタイムアウトを処理します。
- 2. epoll_ctl()を呼び出して、現在の実行環境のepollインスタンスに自分自身を登録します。登録プロセスの2つのステップでは、コールバック関数を指定する必要があります。この関数は、将来、現在のコルーチンを「ウェイクアップ」するために使用されます。
- 3. co_yield_env関数を呼び出して、CPUを放棄します。
- 4.メインのcoroutineepoll_wait()は、読み取り操作のファイル記述子が読み取り可能であることを認識している場合、元の読み取りcoroutineによって登録されたコールバックを実行してウェイクアップします。
2.メインコルチンとコルチンの「スケジューリング」
メインコルーチン[メインスレッドがco_createなどの関数を呼び出すのと同じ理由で、プロセスが低下します]
コンシューマーまたはプロデューサーがブロックされると、CPUはメインコルチンに譲りますが、この時点でメインコルチンは何をしていますか?メインのcoroutineはco_eventloop()関数でビジーです。このco_eventloop(イベントループ)の「スケジューラー」の中心であるこのco_eventloop()は、実際にはepoll / kqueueイベントループ(前述)に基づいているため、通常のスケジューリングとイベント駆動型は密接に関連しています。 、したがって、libcoはネットワークライブラリであるため、それほど日常的なライブラリではありません。バックグラウンドサーバープログラムでは、すべてのロジックはネットワークI / Oを中心に展開され、libcoのような設計には独自の合理性があります。
みんなのために絵を描きます
降伏がブロックされたためにゴルーチン1がCPUをメインスレッドに渡すと、イベントによって駆動され、どのゴルーチンにIOイベントがあるかが判別され、CPUの実行能力が応答するゴルーチンに再開されます。実行後、CPUをyieldでメインコルチンに戻します(このプロセスが繰り返されます)
3.stCoEpoll_t構造
タイマーはイベント駆動型モデルのネットワークフレームワークに不可欠な機能であることがわかっています。ネットワークI / Oのタイムアウト、タイミング待機(pollまたはtimedwait )を含むタイミングタスクはすべてこれに依存します。
一般的に、タイマー機能を使用する場合は、まずタイマーイベント(タイマーイベント)をタイマーに登録します。タイマーイベントを登録する場合は、今後このイベントのトリガー時間を指定する必要があります。トリガー時間に達すると、タイマー通知を受け取ります。