クラッシュしない限り「安全」read
ですが、取得するまで呼び出しを続けない限りEAGAIN
(またはゼロ、つまり相手側が接続を閉じたことを意味します)、データの可用性について誤った仮定をすることがあります。最悪なのは、ほとんどの場合、正常に動作しているように見えることです。
レベル トリガー通知とは対照的に、エッジ トリガー通知は、最後に を呼び出してから準備状態が変化した場合、読み取ることができるデータが残っている場合でも、1 つの通知のみを受け取ることを保証します。
エッジでトリガーされたイベント通知は、Linux では奇妙な動作をしたり、直感的でない動作をすることがあります。そのため、予想とは異なる動作をする可能性があり、たとえば、さらにデータが到着したときに別の通知を受け取ることがあります (そのため、コードは「とにかく動作する」ように見えます) 。保証されているものではありません。で使用すると
、同様の「驚き」がありましたepoll_wait
epoll
eventfd
. エッジ トリガー モードで発生すると予想されるのは、既にブロックされているすべてのスレッドのウェイクアップ (すべて同時に、正確に 1 回) でありepoll_wait
、イベントの後に呼び出すすべてのスレッドは、イベントが消費されて通知されるまでブロックされます。もう一度。実際に行うことは、 を呼び出した最初のスレッドを起こすことepoll_wait
です。再び驚くべきことに、レベル トリガー モードは、イベントを消費して再び準備できるようにする必要があることを除いて、あなたが望むとおりに機能します。でブロックしread
ます)。
したがって、すべてのデータを消費せずに後で再度通知されるのを待つ場合、幸運で「とにかく動作する」か、または非常に長い時間 (おそらく永遠に) 待つ可能性があります。したがって、私の推奨事項は、が得られるまで確実に読み続けることですEAGAIN
。
素朴に読み続けると、遅い送信者を飢えさせる可能性があることに注意してください。あなたが非常に高速な送信者を持っていて、高速な送信者を読み続けると、EAGAIN
(少なくとも相手側が送信し続ける限り!) 見ることはなく、他の送信者を完全に飢えさせるでしょう.
したがって、準備ができているすべての記述子をリストに入れてラウンドロビン方式で読み取り、返されたときにリストから削除することは理にかなっていますEAGAIN
。