Public/tip & tech

libevent 사용 예

quantapia 2011. 6. 1. 14:07

 * 메인 홈페이지 : [http]http://www.monkey.org/~provos/libevent/
  • kqueue, /dev/epoll과 같은 유명한 multiplexer 장치들을 캡슐화한 C 라이브러리. 상당히 안정적. 소스도 작다. :)
  • 1.0c 릴리스.
  • man 페이지 : [http]http://monkey.org/~provos/libevent/event3.html
  • 아래 설명은 man 페이지를 정말로 많이 참조한다음 제가 좀 고쳐본 것입니다.

Contents

[-]
1 설치법
2 필요한 헤더 include
3 설명

1 설치법 #

  • 이유는 모르겠지만 mingw에서 빌드가 자꾸 실패한다. :(
  • 다음과 같이 autotool 기반 빌드를 실행하면 된다. 기본적으로 /usr/local/include, /usr/local/lib에 설치되는데 각각 event.h, libevent.a 가 들어있으면 설치완료.
    # ./configure ; make install clean


2 필요한 헤더 include #

#include <sys/time.h>#include <event.h>

3 설명 #

  • libevent API는 특정 이벤트가 화일지시자(fd)에서 발생하였을 때 또는 주어진 시간이 경과되었을 때 특정 함수를 실행하기위한 장치입니다. 즉, 콜백함수 등록이 필수입니다.
  • libevent API를 사용하기 전에 반드시 event_init()를 실행하여 초기화해주어야합니다.
    void event_init();
  • 이벤트를 처리하기위해 어플리케이션은 event_dispatch()를 호출해주어야합니다. 이 함수는 단지 오류가 발생했을 때만 반환되며, 어플리케이션 프로그램에서 이벤트 핵심부를 대체하는데 사용하게 됩니다. (아마도 ACE의 reactor 이벤트 루프에서 돌리면 딱일듯...)
    int event_dispatch();
  • 시그널 핸들러끼리 경쟁상태에 놓이는 것을 막기위해 libevent API는 event_sigcbevent_gotsig라는 두 변수를 제공하고 있습니다. event_gotsig는 시그널이 수신되었는지 여부를 나타내며, 역호출 함수는 event_sigcb에 설정합니다. 시그널 핸들러가 event_gotsig을 설정한 다음에는, event_dispatch()는 수신된 시그널을 처리하기위해 역호출 함수를 실행합니다. 역호출 함수는 더이상 등록된 이벤트가 없을 경우 1을 반환합니다. 이벤트 라이브러리세 오류발생을 알리기위해서 -1을 반환할 수 있으며, 이런 경우에는 event_dispatch()는 errno에 EINTR을 설정하고 실행을 반환하게 됩니다.
    int (*event_sigcb)(void);int event_gotsig;
  • event_loop()함수는 대기중인 이벤트들에 대한 1-Pass 실행 인터페이스를 제공합니다. 플래그 옵션은 EVLOOP_ONCE와 EVLOOP_NONBLOCK을 지정할 수 있습니다. 옵션을 0으로 지정(아무 옵션도 지정하지 않으면)할 경우에는 이벤트가 일어날 때까지 블럭상태로 대기하고 이벤트들을 모두 처리한 후 실행을 반환합니다. (event_dispatch()와 같은 효과. 실제 코드도 그렇게 되어있습니다)
    int event_loop(int flags);
  • 함수를 호출하기에 앞서 libevent API 함수에게는 (필요할경우) 미리 할당된 이벤트 구조체들을 제공할 책임이 있습니다.
  • event_set() API 함수는 나중에 event_add() 또는 event_del()를 호출하는데 사용될 이벤트 구조체 ev를 준비하는데 사용합니다.
    • 준비된 이벤트는 아래 선언에서 4번째 매개변수로 지정된 역호출 함수포인터 fn을 나중에 호출하게 됩니다. (이 함수포인터의 매개변수들은 각각 event_set() 함수의 fd, event, arg에 대응합니다)
    • fd는 이벤트 발생여부를 감시당하는 함수지시자를 뜻합니다. 이벤트는 EV_READ, EV_WRITE, 또는 전체( EV_READ|EV_WRITE ) 중 하나를 지정할 수 있습니다. EV_PERSIST을 추가로 설정하면 event_add()가 차후 event_del()이 실행될 때까지 계속 유지되도록 지정하는 것이 가능합니다.( <!> 계속 연달아 발생한다는 의미? 해석이 모호...) 이렇게 설정함으로서 어플리케이션은 fd로부터 읽기/쓰기 가능여부를 블럭상태에 놓이지 않고 각각 알 수 있습니다.
      • 함수 포인터 fn은 이벤트가 발생한 fd와 EV_TIMEOUT, EV_SIGNAL, EV_READ, EV_WRITE 중 하나로 지정된 event 옵션을 매개변수로 하여 실행됩니다.
  • void event_set(struct event *ev, int fd, short event, void (*fn)(int, short, void *), void *arg);
  • 일단 이벤트가 초기회되면, ev 구조체는 반복적으로 event_add()event_del()을 통하여 사용할 수 있으며, 역호출 함수포인터와 매개변수가 변경할 경우가 아니라면 다시 초기화할 필요가 없습니다.
  • event_add() 함수는 ev 이벤트의 실행을 스케줄링 처리하는데, 이 함수를 실행한 시점부터 event_set()에서 지정한 이벤트가 발생하거나 tv로 지정한 타임아웃이 경과되면 이벤트가 발생하게 됩니다. tv를 NULL로 지정하면 타임아웃 설정을 하지 않는 것이므로, fd에 해당 이벤트가 발생할 경우에만 호출됩니다.
    • ev 매개변수가 가리키는 이벤트는 event_set()에 의해 이미 초기화되어있어야하며, 타임아웃되거나 event_del()에 의해 제거되기 전에는 event_set()로 다시 초기화되지 않아야합니다. 만약 ev 매개변수로 지정된 이벤트가 이미 타임아웃이 설정되어있다면 이전 타임아웃값은 새로운 타임아웃 값으로 교체됩니다.
    • event_del()함수는 ev 매개변수가 가리키는 이벤트를 취소합니다. 이벤트가 이미 실행중이거나 아직 event_add()로 추가되지 않았다면, 아무런 실행도 하지 않은 것과 같게 됩니다.
  • int event_add(struct event *ev, struct timeval *tv);int event_del(struct event *ev);
  • event_pending() 함수는 event 매개변수로 지정된 이벤트가 실행을 대기하고 있는지 여부를 검사하는데 사용합니다. 만약 이벤트에 EV_TIMEOUT 옵션이 정의되어있고 tv가 NULL이 아니라면 tv안에 지정된 타임아웃 만료시간값이 반환됩니다.
    int event_pending(struct event *ev, short event, struct timeval *tv);
  • event_initialized() 매크로는 지정한 이벤트 구조체 ev가 초기화되었는지 여부를 검사합니다.
    int event_initialized(struct event *ev);
  • evtimer_set(), evtimer_add(), evtimer_del(), evtimer_initialized(), evtimer_pending() 함수는 타임아웃 처리만 필요할 경우 일반적인 처리부분을 요약하여 선언해둔 것입니다. fd는 0으로 지정되며 이벤트 타입은 EV_TIMEOUT이 될 것입니다. (이것은 사용자 정의 이벤트와 같은 역할을 하지 않을까요?)
    void evtimer_set(struct event *ev, void (*fn)(int, short, void *), void *arg);void evtimer_add(struct event *ev, struct timeval *);void evtimer_del(struct event *ev);int evtimer_pending(struct event *ev, struct timeval *tv);int evtimer_initialized(struct event *ev);
  • signal_set(), signal_add(), signal_del(), signal_initialized(), signal_pending() 역시 축약된 함수들입니다. 이벤트 타입은 모두 EV_SIGNAL|EV_PERSIST 로 설정됩니다.
    void signal_set(struct event *ev, int signal, void (*fn)(int, short, void *), void *arg);void signal_add(struct event *ev, struct timeval *);void signal_del(struct event *ev);int signal_pending(struct event *ev, struct timeval *tv);int signal_initialized(struct event *ev);
  • EVENT_NOKQUEUE 환경변수가 설정되어있으면 kqueue에 대한 기능 지원을 끌 수 있습니다.

http://www.redwiki.net/wiki/wiki.php/libevent 에서 펌.