libevent是一個開源的事件控制機制,若是不想陷入多進程或多線程的困擾,那麼libevent將是很合適的工具。安全
libevent提供了不少的API來管理和控制事件,可用於設計讀、寫、信號、定時等各類類型的事件處理,其使用主要有一下幾個步驟:
一、首先須要初始化一個event_base結構體,它是libevent的入口,形如
struct event_base* base=event_init();
在新版本中推薦使用線程安全的 event_base_new()來替換event_init();
初始化後就創建了一個libevent的基本框架,接下來就是向框架裏註冊事件和相應的事件回調函數了。
二、設置註冊事件和回調函數:
設置事件使用API: event_set,原型:
event_set(struct event *ev, int fd, short event, void (*func)(int, short, void *), void *arg);
ev是聲明的event結構體名稱;
fd是監視事件對應的文件描述符;
short event是指定事件類型,能夠是:EV_READ,EV_WRITE或EV_READ|EV_WRITE,一般配合使用EV_PERSIST,使事件在執行後不被刪除,直到調用event_del()。
*func(int, short, void *)是編寫好的回調函數指針,指明在監聽的事件發生時要作的處理,其中void*是有*arg指定的參數,int 和short則對應與 int fd和 short event;
三、添加事件
事件設置以後,調用API:
event_add(struct event* ev,timeout);
ev是以前設置的event結構體指針,timeout是超時設置,沒有可填NULL;
至此,對事件的初始化和設置已完成。
四、最後一步是事件的運行
調用: event_base_dispatch(base);
這是一個無線循環,還有不少的API提供各類不一樣須要,如:
event_base_set(),event_base_dispatch(), event_base_loop(), bufferevent_base_set() 等
簡單的例子,libevent配合socket很是方便地完成監聽多客戶端的鏈接(部分代碼):
int main(int argc, char* argv[])
{
struct sockaddr_in my_addr;
int sock;
sock = socket(AF_INET, SOCK_STREAM, 0);
int yes = 1;
setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int));
memset(&my_addr, 0, sizeof(my_addr));
my_addr.sin_family = AF_INET;
my_addr.sin_port = htons(PORT);
my_addr.sin_addr.s_addr = INADDR_ANY;
bind(sock, (struct sockaddr*)&my_addr, sizeof(struct sockaddr));
listen(sock, BACKLOG);
struct event listen_ev;
base = event_base_new();//初始化
event_set(&listen_ev, sock, EV_READ|EV_PERSIST, on_accept, NULL);//設置事件
event_base_set(base, &listen_ev);
event_add(&listen_ev, NULL);//添加
event_base_dispatch(base);//運行
return 0;
}
以上只是簡單的使用步驟,後續還有不少其餘的API和使用介紹