NeiNeigh's blog

覚書のようなブログ.PC・アプリケーション・プログラミング・オーディオ・アニメ

libeventの使い方

だんだんlibeventがどんなものかわかってきたのでメモ
libeventはスレッドセーフでないため,マルチスレッドで使う場合にはこのリソース(event_base)を分けて管理する必要がある.これについては最後に記す.

event_base1つだけで簡単にやる方法

ここより引用
libevent + 使い方 | ninxit.blog

1.event_init で初期化
2.event_set でイベント設定
3.event_add で設定したイベントを追加
4.event_del で追加したイベントを削除
5.event_dispatch でイベント通知の検知を開始

だいたいこんな感じである.順番に見ていく

1.event_init()
event_init();

これで初期化を行い,libeventのリソースを生成する.

2.event_set()
struct event ev;
event_set(&ev, listener, EV_READ | EV_PERSIST, handler, &ev);

イベントの内容をevent構造体にセットする.引数は順番に

  • セットするevent構造体
  • 監視対象のファイルディスクリプタ.EV_READは読み込みイベント,EV_WRITEは書き込みイベント,EV_PERSISTは継続フラグを表してる.読み込みイベントを監視して,一回そのイベントが起こっても継続して監視するときは上記のような引数を渡す.
  • 監視対象のイベント
  • イベントハンドラの引数.どこのwebサイトみてもだいたいevent構造体を渡している.たぶんこれは,イベントが終わった時にハンドラで構造体を削除するため.

である.
ちなみにマニュアルに載ってるAPIはたぶんこれ.

void event_set(struct event *ev, int fd, short event, void (*cb)(int, short, void *), void *arg)

ここについてはこのページに詳しく載っている.
http://www.ninxit.com/blog/2008/02/13/libevent-%E4%BD%BF%E3%81%84%E6%96%B9/

そしてそこから,第3引数に関する記述を引用しておく.

指定するとイベント通知を受け取った後も継続してイベント通知を受け取る。
逆に指定しなければ、イベント通知を受け取った後、内部で設定したイベントが削除され、
再度 event_add しない限り、イベント通知を受け取らなくなる。
また、event_add の第2引数に timeval 構造体を渡していると、
EV_PERSISTを追加していても、イベント通知を受け取った後、
内部で設定したイベントが削除される。
timeval 構造体を渡した場合、イベント通知を受け取った後、
もう一度 event_add を行う必要がある。

3.event_add()
event_add(&ev, NULL);

設定したevent構造体を登録する.第2引数でイベント監視のタイムアウトを設定する.
マニュアルに載ってるAPIはこれ.

event_add(struct event *ev, const struct timeval *timeout); 
4.event_del()

これはイベント監視を終了するときに呼ぶ.通常はハンドラ内で呼び出す.だから4番目にこれの説明を書くのはちょっとおかしくて,次のdispatchを先に書くべきだけど引用元の順番がこうなってたので.

event_del(ev);
5.event_dispatch()

イベント監視を開始.

event_dispatch();

これで非同期に監視が開始される.もちろん非同期だから,イベント待ち状態でこの関数のところでずっと止まってるなんてことはなく,処理は進んでいく.原理はよくわからないが,いい感じのシステムコールが呼ばれ,いい感じにOSがやってくれてるんだと思う.

6.ハンドラの書き方

こちらが参考になる.ソースコードも見やすいので全体の流れをつかむときはここを見ると良い.
libeventでechoサーバをつくってみた - in the mythosil

見るとわかるが,ハンドラの第1引数はソケット,第2引数には監視対象のイベントフラグ,第3引数は任意の引数で定義されている.
1と2は自動的に渡されて,3にはevent_set()の第5引数が渡されるものだと考えられる.

複数のevent_baseを使う方法

こちらの方法は,とりあえず自分が使う予定がないのでここには詳しく書かない.
こちらを見るとわかると思う.
複数の event_base を使う場合 - mtaneda’s diary