Libevent簡介
The libevent API provides a mechanism to execute a callback function when a specific event occurs on a file descriptor or after a timeout has been reached. Furthermore, libevent also support callbacks due to signals or regular timeouts.
Libevent的API提供了這樣的一套機制: 當指定文件描述符中一個特定的事件發(fā)生,或者超時時間到達后執(zhí)行指定的回調(diào)函數(shù)。 此外,libevent回調(diào)功能也支持由信號或者常規(guī)的超時觸發(fā)。 注意其許可協(xié)議為BSD-style的協(xié)議,可以在商業(yè)級產(chǎn)品中采用而不必開源。
1.編譯安裝
ubuntu下可以使用apt的方法直接安裝:
 ~$ sudo apt-get install libevent
或者使用
 ~$ wget http://monkey.org/~provos/libevent-1.4.13-stable.tar.gz  ~$ tar –xzvf libevent-1.4.13-stable.tar.gz  ~$ cd libevent-1.4.13-stable  ~$ ./configure  ~$ make  ~$ sudo make install 
2.庫的使用
可以從這幾個簡單的例子中了解到libevent的基本使用方法。編譯時需加上 "-levent"參數(shù)。
2.1.I/O事件(對應EV_READ、EV_WRITE)
下面提供了一個有所省略簡單使用libevent返回系統(tǒng)時間的服務端程序片段。
1 void get_time(int fd,short event,struct event *arg) /**//*獲取系統(tǒng)時間并將其往回write*/ 2  { 3 …… 4 localtime_r(&now,&t); 5 asctime_r(&t,buf); 6 write( fd,buf,strlen(buf) ); 7 …… 8 } 9 void con_accept(int fd,short event,void *arg) /**//*提供給事件的回調(diào)函數(shù),接收一個連接*/ 10  { 11 struct sockaddr_in s_in; 12 socklen_t len = sizeof(s_in); 13 int ns = accept(fd,(struct sockaddr *) &s_in,&len); 14 struct event *ev = malloc(sizeof(struct event)); 15 event_set(ev,ns,EV_WRITE,(void *)get_time,ev); 16 event_add(ev,NULL); 17 } 18 19 int main() 20  { 21 int sockfd = socket(PF_INET,SOCK_STREAM,0); 22 struct sockaddr_in s_in; 23 …… 24 bind(sockfd,(struct sockaddr*) &s_in,sizeof(s_in)); 25 listen(sockfd,5); 26 event_init(); //libevent初始化 27 28 struct event ev; 29 event_set(&ev,sockfd,EV_READ|EV_PERSIST,con_accept,&ev); 30 //設置事件屬性為可讀、持續(xù),回調(diào)函數(shù)為con_accept() 31 event_add(&ev,NULL);//添加事件,未設置超時時間 32 event_dispatch();//進入libevent主循環(huán) 33 return 0; 34 } 35
2.2. 信號處理事件(對應EV_SIGNAL)
1 static void signal_cb(int fd, short event, void *arg) 2  { 3 struct event *signal = arg; 4 printf("%s: got signal %d\n", __func__, EVENT_SIGNAL(signal)); 5 if (called >= 2) 6 event_del(signal); //如果調(diào)用了兩次以上,就刪除這個信號 7 called++; 8 } 9 10 int main (int argc, char **argv) 11  { 12 struct event signal_int; 13 event_init();//libevent初始化 14 event_set(&signal_int, SIGINT, EV_SIGNAL|EV_PERSIST, signal_cb, &signal_int); 15 //設置事件屬性為信號觸發(fā)、持續(xù),回調(diào)函數(shù)為con_accept() 16 event_add(&signal_int, NULL); //添加事件 17 event_dispatch();//進入libevent主循環(huán) 18 return 0; 19 } 20
2.3.常規(guī)超時處理(對應EV_TIMEOUT)
1 static void timeout_cb(int fd, short event, void *arg) 2  { 3 struct timeval tv; 4 struct event *timeout = arg; 5 int newtime = time(NULL); 6 printf("%s: called at %d: %d\n", __func__, newtime, 7 newtime - lasttime); 8 lasttime = newtime; 9 evutil_timerclear(&tv); 10 tv.tv_sec = 2; 11 event_add(timeout, &tv); 12 } 13 14 int main (int argc, char **argv) 15  { 16 struct event timeout; 17 struct timeval tv; 18 event_init();//libevent初始化 19 evtimer_set(&timeout, timeout_cb, &timeout); 20 //實際上該函數(shù)對應的是event_set(timeout, -1, 0, timeout_cb,&timeout) 21 evutil_timerclear(&tv); //如果有時間清理函數(shù)則直接對應timerclear(),如果沒有則將tv_sec和tv_usec設置為0 22 23 tv.tv_sec = 2; 24 event_add(&timeout, &tv); 25 lasttime = time(NULL); 26 event_dispatch(); 27 return 0; 28 } 29
|