8

関数を使用して libuv でイベント ループを実行する場合uv_run、次の値で使用される「モード」パラメーターがあります。

UV_RUN_DEFAULT
UV_RUN_ONCE
UV_RUN_NOWAIT

最初の 2 つは明らかです。UV_RUN_DEFAULTイベントがなくなるまでイベント ループを実行し、UV_RUN_ONCEループから 1 つのイベントを処理します。ただし、UV_RUN_NOWAIT別のモードではなく、他の 2 つの値のいずれかと OR できるフラグのようです。

デフォルトでは、この関数はイベントの処理が完了するまでブロックし、非ブロックにしUV_RUN_NOWAITますが、私が見つけることができるドキュメントはそこで終わります。私の質問は、イベント ループ ノンブロッキングを実行する場合、コールバックはどのように処理されるかということです。

libuv イベント モデルはシングル スレッド (リアクター パターン) であるため、コールバックを呼び出すにはブロックする必要があると思いますが、メイン スレッドが占有されている場合、処理後のイベントはどうなりますか? libuv が再びメイン スレッドの制御を取得するまで、コールバックは「キュー」に入れられますか? または、コールバックは別のスレッドでディスパッチされますか?

4

1 に答える 1

12

コールバックも同じ方法で処理されます。にあるスレッド内で実行されuv_run()ます。

ドキュメントごと:

  • UV_RUN_DEFAULT: 参照カウントがゼロになるまでイベント ループを実行します。常にゼロを返します。
  • UV_RUN_ONCE: 新しいイベントを 1 回ポーリングします。保留中のイベントがない場合、この関数はブロックされることに注意してください。完了するとゼロを返します (アクティブなハンドルまたは要求が残っていない) か、さらにイベントが予想される場合はゼロ以外を返します (将来いつかイベント ループを再度実行する必要があることを意味します)。
  • UV_RUN_NOWAIT: 新しいイベントを 1 回ポーリングしますが、保留中のイベントがない場合はブロックしません。

プログラムにソケットをリッスンする単一のウォッチャーがある場合を考えてみましょう。このシナリオでは、ソケットがデータを受信したときにイベントが作成されます。

  • UV_RUN_DEFAULTソケットにデータがない場合でも、呼び出し元をブロックします。uv_run()次のいずれかの場合、 呼び出し元は から戻ります。
    • ループは明示的に停止されました。uv_stop()
    • ループ内で実行されているウォッチャーはもうありません。たとえば、唯一のウォッチャーが停止されました。
  • UV_RUN_ONCEソケットにデータがない場合でも、呼び出し元をブロックします。uv_run()次のいずれかが発生した場合、 呼び出し元は から戻ります。
    • ループは明示的に停止されました。uv_stop()
    • ループ内で実行されているウォッチャーはもうありません。たとえば、唯一のウォッチャーが停止されました。
    • 最大 1 つのイベントを処理しました。たとえば、ソケットがデータを受信し、ユーザー コールバックが呼び出されました。uv_run()追加のイベントを処理する準備ができている可能性がありますが、現在の呼び出しでは処理されません。
  • UV_RUN_NOWAITソケットにデータがない場合に返されます。

多くの場合、非ブロッキング方式でイベント ループを実行すると、他のイベント ループと統合されます。バックエンド作業用の libuv と Qt UI (独自のイベント ループによって駆動される) の 2 つのイベント ループを持つアプリケーションを考えてみましょう。非ブロッキング方式でイベント ループを実行できるため、単一のスレッドが両方のイベント ループでイベントをディスパッチできます。以下は、1 つのスレッドで処理される 2 つの libuv ループを示す単純な概要です。

uv_loop_t *loop1 = uv_loop_new();
uv_loop_t *loop2 = uv_loop_new();

// create, initialize, and start a watcher for each loop.
...

// Handle two event loops with a single thread.
while (uv_run(loop1, UV_RUN_NOWAIT) || uv_run(loop2, UV_RUN_NOWAIT));

を使用しないとUV_RUN_NOWAITloop2一度だけ実行されるloop1か、loop1のウォッチャーが停止されます。

詳細については、libuv の紹介の高度なイベント ループプロセスのセクションを読むことを検討してください。

于 2013-06-26T20:15:24.650 に答える