libevent是一個c語言寫的事件驅動庫,輕量級,專一於網絡,跨平臺特性好,支持多種 I/O 多路複用.支持I/O,定時器和信號等事件,容許設置註冊事件優先級.網絡
struct event_base *event_base_new(void); struct event_base *event_init(void);
例:socket
struct event_base *base = event_init();
typedef void (*event_callback_fn)(evutil_socket_t, short, void*); struct event *event_new(struct event_base *, evutil_socket_t, short, event_callback_fn, void *); int event_assign(struct event *, struct event_base *, evutil_socket_t, short, event_callback_fn, void *); void event_set(struct event *ev, int fd, short events, event_callback_fn, void *arg); void event_base_set(struct event_base *,struct event*);
event_assign()的做用就是把給定的event類型對象的每個成員賦予一個指定的值。函數
event_new()的實現實際上是間接的調用的event_assign(),首先調用mm_malloc分配一塊內存,而後調用event_assign來給event類型的對象各個成員賦值。oop
event_set() 使用指定的句柄、關注的事件、事件發生時的回調函數、回調函數的額外參數,初始化設置struct event結構對象,綁定到全局current_base,設置此event結構對象的優先級,默認爲current_base中總有限級數的一半學習
event_base_set() 將事件綁定到事件根基,即設置event從屬的event_base,指明event註冊到哪一個event_base實例上測試
例:spa
//SIGINT 信號事件初始化 //假定已建立事件根基struct event_base *base //方式一: struct event sigint_ev; event_assign(&sigint_ev,base,SIGINT, EV_SIGNAL | EV_PERSIST,sigint_cb,NULL); //方式二: struct event sigint_ev ; event_set(&sigint_ev, SIGINT, EV_SIGNAL | EV_PERSIST, sigint_cb, NULL); event_base_set(base, &sigint_ev); //方式三: struct event *sigint_ev; sigint_ev = event_new(base,SIGINT,EV_SIGNAL | EV_PERSIST, sigint_cb, NULL); //方式四: struct event* sigint_ev = (struct event*)malloc(sizeof(struct event)); //sigint_ev檢測非空和置零後,用event_assign 或者event_set + event_base_set 初始化事件.
#define evtimer_set(ev, cb, arg) event_set(ev, -1, 0, cb, arg)
#define evsignal_new(base,signum,cb,arg) \ event_new(base,signum,EV_SIGNAL|EV_PERSIST,cb,arg)
void event_add(struct event* ,struct timeval *);
void event_base_dispatch(struct event_base *); void event_base_loop(struct event_base *,int );
gcc -o test test.c -levent指針
#include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <malloc.h> #include <event.h> #include <sys/time.h> #include <signal.h> #include <string.h> #define BUF_SIZE 1024 typedef struct{ struct event *ev; char *buf; struct timeval *tv; }rw_st; void wr_cb(int fd, short event, void *arg); void rd_cb(int fd, short event, void *arg); struct event_base *base = NULL; //定時事件 struct timeval tv; struct event time_ev; void time_cb(int fd, short event, void *arg) { printf("time_cb : 5s timer wakeup\n"); event_add(&time_ev,&tv); } //標準輸入 讀事件 //輸入一行,把讀事件刪掉,添加寫事件 void rd_cb(int fd,short event, void *arg) { if(event & EV_TIMEOUT){ printf("io read time out(2s)!\n"); return ; } rw_st* rd_st = (rw_st*)arg; int len = read(fd, rd_st->buf, BUF_SIZE); rd_st->buf[len-1] = '\0'; printf("rd_cb (stdin): %s \n",rd_st->buf); event_del(rd_st->ev); event_set(rd_st->ev, STDOUT_FILENO, EV_WRITE | EV_PERSIST, wr_cb,(void*)rd_st); event_add(rd_st->ev,NULL); } //標準輸出 寫事件 //輸出,把寫事件刪掉,添加讀事件,邊寫邊讀 void wr_cb(int fd, short event, void *arg) { rw_st *wr_st = (rw_st*)arg; printf("wr_cb (stdout): %s\n",wr_st->buf); memset(wr_st->buf,0,BUF_SIZE); event_del(wr_st->ev); event_set(wr_st->ev, STDIN_FILENO, EV_READ | EV_PERSIST, rd_cb, (void*)wr_st); event_add(wr_st->ev,wr_st->tv); } //SIGINT 信號事件 void sigint_cb(int fd, short event, void *arg) { struct timeval tv_1s = {1,0}; printf("SIGINT : EXIT IN 1s\n"); event_base_loopexit(base,&tv_1s); } //SIGHUB 信號事件 void sighup_cb(int fd, short event, void *arg) { printf("SIGHUP: EXIT AT ONCE\n"); event_base_loopbreak(base); } int main() { printf("pid = %ld\n",getpid()); base = event_init(); //定時器 tv.tv_sec = 5; tv.tv_usec = 0; evtimer_set(&time_ev, time_cb, NULL);//一次性,默認全局的current_base // event_set(&time_ev,-1,0,time_cb,NULL); // event_base_set(base, &time_ev); //可省,在這裏current_base等同base event_add(&time_ev,&tv); //io 讀事件 指針 event_new char buf[1024] = {0}; struct timeval io_tv = {2,0}; rw_st *rd_st = (rw_st*)malloc(sizeof(rw_st)); memset(rd_st,0,sizeof(rw_st)); struct event *io_ev = (struct event*)malloc(sizeof(struct event)); memset(io_ev,0,sizeof(struct event)); rd_st->ev = io_ev; rd_st->buf = buf; rd_st->tv = &io_tv; event_assign(rd_st->ev,base,STDIN_FILENO, EV_TIMEOUT | EV_READ | EV_PERSIST,rd_cb,(void*)rd_st); event_add(rd_st->ev,rd_st->tv); //SIGINT 信號事件 struct event sigint_ev; event_assign(&sigint_ev,base,SIGINT, EV_SIGNAL | EV_PERSIST,sigint_cb,NULL); // event_set(&sigint_ev, SIGINT, EV_SIGNAL | EV_PERSIST, // sigint_cb, NULL); //event_base_set(base, &sigint_ev); event_add(&sigint_ev,NULL); // struct event *sigint_ev = event_new(base,SIGINT, // EV_SIGNAL | EV_PERSIST, sigint_cb, NULL); // event_add(sigint_ev,NULL); //SIGHUP 信號事件 //測試: $ kill -SIGHUP pid struct event *sighup_ev; sighup_ev = evsignal_new(base, SIGHUP, sighup_cb, NULL); event_add(sighup_ev,NULL); event_base_dispatch(base); //event_base_loop(base,0); event_free(sighup_ev); event_base_free(base); free(rd_st); printf("EXIT\n"); return 0; }