問題タブ [epollet]
For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.
linux - マルチスレッドの epoll サーバー: 同じ epoll fd でスリープしている N 個のスレッドを起動します
マルチスレッドの epoll サーバーを使用しています。epoll fd を作成すると、X スレッドがスリープ状態になり、その同じ epoll fd からのイベントを待機しepoll_wait()
ます。
ここで私の質問は次のとおりです。N > 1 && N < X で、N 個のスレッドをウェイクアップするにはどうすればよいですか?
これまで、Linux 固有の eventfd 機能を使用してきました。これは 1 つのスレッドだけでかなりうまく機能しましたが、複数のスレッドが同じ epoll fd を待機していると、問題が発生します。
ケース 1) LT: 「レベル トリガー」モードで eventfd を追加すると、eventfdへの書き込み時にすべてのスレッドが起動します。これは、レベル トリガー モードがどのように機能するかです。
N = X
ケース 2) ET: 「エッジ トリガー」モードで eventfd を追加すると、eventfdに書き込むときに1 つのスレッドのみが起動します。これがエッジ トリガー モードのしくみEAGAIN
ですread(eventfd, ...);
。
N = 1
ケース 3) セルフパイプ トリックも試しましたが、パイプに N 回書き込むと N スレッドが起動します。信頼性が低く、1 つのスレッドがパイプから 2 つの「トークン」を読み取ることもあれば、1 つまたは 3 つ読み取ることもあります。
N = ランダム
私が試したすべてのケースで、N=N だけを取得することはできません。N スレッドのみを起動することはできませんが、1、ALL、または RANDOM のいずれかです。私は何が欠けていますか?何かご意見は?EFD_SEMAPHORE
注:そこからの助けなしに、eventfd固有のフラグも試しました。
event-handling - epoll スレッドセーフのファイル記述子のリアームはありますか?
この質問からepoll_ctl(2)
、別のスレッドがブロックしているときに呼び出すことができることがわかりましたepoll_wait(2)
。まだ質問があります。
フラグを使用epoll
すると、EPOLLONESHOT
1 つのイベントのみが発生し、fd を使用して再準備する必要がありますepoll_ctl(2)
。これは、1 つのスレッドのみが fd から読み取り、結果を適切に処理するために必要です。
以下は、想定される問題をある程度視覚化したタイムラインです。
チャンクが受信された後に fd がリアームされると、疑問符はどうなりますか? epoll
イベントを発生させますEPOLLIN
か、それともソケットが読み取り可能であっても無期限にブロックしますか? 私のアーキテクチャはまったく賢明ですか?
linux - epoll_waiting でないときに epoll イベントが監視されていますか
私はイベントベースのプログラミングにかなり慣れていません。私は、読み取り/書き込みの準備が整ったファイルのみを通知するように見えるepoll
's edge-modeを試しています (既に準備ができているか準備ができているかに関係なく、すべての準備ができているファイルを通知する level-mode とは対照的です)。
よくわからないのは、エッジモードでは、私がepoll_wait
ing していないときに発生する準備イベントが通知されるかどうかです。まだリアームされていないワンショット ファイルのイベントはどうなりますか?
なぜそれを求めているのかを説明するために、次のシナリオを考えてみましょう。
- 10 個のノンブロッキング ソケットが接続されている
- edge-mode + oneshot
epoll_ctl
で、ソケットの読み取り準備が整ったときに反応するように構成します。EPOLLET | EPOLLONESHOT | EPOLLIN
epoll_wait
何かが起こる (最大 10 件のイベントを報告)- Linux がプロセスを起動し、ソケット #1 と #2 の準備ができていることを報告します
- I
read
とプロセス データ ソケット #1 (までE_AGAIN
) - I
read
とプロセス データ ソケット #2 (までE_AGAIN
) - 私がそれをしている間、ソケットSはデータを受け取ります
- すべてのイベントを処理したので、トリガーされたファイルを
epoll_ctl
inEPOLL_CTL_MOD
モードでリアームします。 epoll_wait
私のループは次のイベントのバッチに戻ります
わかりました、それで、ソケットSの準備ができていることを最後にepoll_wait
常に通知しますか? Sが #1 の場合のイベント(つまり、再装備されていない) ?
c - EPOLLOUT が EPOLLIN の処理方法を変更するのはなぜですか?
イベントが結合されているかどうかについてのドキュメントは不明であり、私のテストでは、それらが常にではなく、場合によっては結合されていることが示されています。
考慮してくださいman 7 epoll
:
エッジ トリガーのepollでも、データの複数のチャンクを受信すると複数のイベントが生成される可能性があるため 、呼び出し元には EPOLLONESHOT フラグを指定するオプションがあります...
および Q&A セクション:
Q7 epoll_wait(2) 呼び出しの間に複数のイベントが発生した場合、それらは結合されますか、それとも別々に報告されますか?
A7 統合されます。
マニュアルの最初のステートメントは、ソケットからの読み取り、パケットの到着、それの読み取り、別のパケットの到着などの状況で複数の EPOLLIN イベントを受信できることを意味していると思います。また、Q&A セクションの回答は、EPOLLIN や EPOLLOUT などのさまざまなイベントに関するものです。私が間違っている場合は、私を修正してください。
epoll がどのように機能するかをよりよく理解するためにいくつかのコードをいじっていましたが、別のイベントが設定されているかどうかに基づいて、同じ種類のイベントに関して異なる動作をしているように見えます。より正確には、EPOLLIN のみを待機している場合、複数の入力が 1 つのイベントを生成しますが、EPOLLIN と EPOLLOUT の両方を待機している場合、複数の入力が複数のイベントを生成します。
これをテストするために使用したコードは次のとおりです。
Return キーを押した後の出力は、EPOLLIN と EPOLLOUT の両方が受信されたことを示しています。このメッセージは、Return キーが押された回数だけ表示され、EPOLLOUT のみが生成されていることを示しています。
しかし、EPOLLOUT フラグを指定せずにプログラムをコンパイルし、Return キーを何度も押すと、1 つのイベントが 1 回だけ報告されます。
呼び出しを削除するread
と、EPOLLOUT が設定されている場合は EPOLLIN が引き続き報告されますが、EPOLLIN のみが設定されている場合は報告されません。
待機しているイベントに依存する動作ですか、それともテスト コードに何か問題がありますか? 依存している場合は、今後も変わらないので安心できますか?