ネットワーク非同期I/Oについて(select/epoll)

c.f.

blog.takanabe.tokyo

プログラム所感

ネットワーク非同期I/Oについて、特にselectとepollの違いを確認しながらプログラムを書いてみた。あえてできるだけユーザ関数は作成せずに、手続き的に上からコードを見ていけるように配慮している。コメントも入れないことにした(デバッグ出力はあるけれど)。

テストとして、2クライアントからの接続要求・送信・受信・切断をテストしているが、その際にはwhileループをsleepで遅延させてテストしている。

同期I/O(Blocking I/O)の場合はスレッドを作成して処理スループットを上げる必要があるが、select/epollではシングルスレッドで処理を行うことで、スレッドが大量に生成される場合のオーバヘッド(コンテキストスイッチのオーバーヘッド、キャッシュの再利用性の低下、を含む)を軽減する。さらにepollは、処理すべきソケット=データが到着したソケット、だけを検出することができるので(これがO(1)の所以)、selectのように監視対象の全てのソケットに対してデータが到着したかどうかを確認する必要(O(n)の所以)がないので、より効率的である。このようなシングルスレッドのプロセスを、CPUの数に合わせて複数起動しておくことで、サーバのリソース利用効率を最大化できる。

なお、shutdownでは、epollインスタンスに登録されたソケットが登録解除されないので、closeを使っている

また、クライアント側のpythonのraw_input()は一行で4095文字以上を一度に読み込むことができないようなので(4500文字よみこんだら404と4095に分割され、結合しても入力したデータは正確に読み込めていなかった)、大きい送信データサイズの確認は標準入力ではなくスクリプト内で作成した文字列を使った。

select

gist.github.com

epoll

gist.github.com

client example

gist.github.com

How to use epoll? A complete example in C - Banu Blog