エッジトリガ (epoll) の話

エッジトリガのメリットとしては、「データが貯まった状態で処理を後回ししても起こされない」というのもあるみたいだけど、これはEPOLLONESHOTというオプションを使うとレベルトリガでも実現可能。

epollであえてエッジトリガを使うとすれば、「ノンブロッキングI/Oでいつも最後までデータを読んでるから、レベルトリガはただの無駄だよねー」とかいうときの気持ちの問題ではなかろうか。

http://d.hatena.ne.jp/nishidakeisuke/20080703/p1

エッジトリガとレベルトリガで、コーディングの差が大きくなるのは、むしろデータを書く場合なんじゃないのかなぁ。レベルトリガだと、

  • send(2) が EAGAIN を返したら epoll に fd を登録
  • アプリケーション側のバッファが空になったら、epoll から fd を削除

というコードを書かないといけない (と思う) のに対し、エッジトリガなら、fd は epoll に登録しっぱなしにしておいて、

  • アプリケーション内で書込が発生する際
    • アプリケーション側のバッファが空であれば即 send(2)
    • バッファが空でなければ、バッファに追記
  • epoll イベントを受け取ったら、send(2)

という形で書くことができる (と思う)。

結局、アプリケーション内でちゃんとバッファリングを行う場合は、(読み書きともに) エッジトリガで十分なわけだし、その方が、より軽く、より簡潔なコードになるんじゃないかなと思った。

自分は (select(2) や poll(2) との互換性を保つのが面倒だから) いままでレベルトリガしか使ったことがないので、外しているかもしれませんが。

追記: エッジトリガはステート情報を交換するための API、レベルトリガはステートを確認するための API と言うといいのかなぁ。

C++ サーバフレームワークの最適化

Kazuho Oku on Twitter: "とりあえず分散型 Twitter 技術デモの段階までは作る。Twitter への乗り入れモデルも実装するかも" とか言ってしまった都合上、高速なサーバフレームワークが必要になるので、Kazuho@Cybozu Labs: C++ テンプレートを使って高速な高機能サーバを書く方法 の最適化を始めた。目標は、元来のデザインを保ったまま、epoll ベースで動くようにすること。とりあえず、 rev. 15405 の段階で、 select(2) を使ったエッジトリガによる実装が動き出してる。

まだ、エッジトリガを使う場合にほぼ必須な、自前でのステート管理が遅かったりするけど。