1、libevent的使用(libevent例子)
static void
signal_cb(evutil_socket_t sig, short events, void *user_data)
{
struct event_base *base = user_data;
struct timeval delay = { 2, 0 };
printf("Caught an interrupt signal; exiting cleanly in two seconds.\n");
event_base_loopexit(base, &delay); //退出loop
}
int main(){
struct event_base *base;
base = event_base_new(); //创建event_base
struct event *signal_event = evsignal_new(base, SIGINT, signal_cb, (void *)base); //创建信号event
event_base_dispatch(base); //开始循环 判断注册在其上的事件的发生-->调用event的回调函数
event_free(signal_event); //释放内存
event_base_free(base);
return 0;
}
libevent的使用步骤如下:
- 创建一个ebent_base
- 创建事件并添加事件: 信号事件、 套接字事件、定时器事件
- 开始事件处理(loop)
- 退出loop、释放资源
2、libevent学习
从第1部分可知、libevent中最重要的部分为event_base和event 、通过学习了libevent的源码后、画出了部分结构之间的关系。
2.1、event
其中event最主要的函数为:
/*新建一个event*/
struct event *
event_new(struct event_base *base, evutil_socket_t fd,
short events, void (*cb)(evutil_socket_t, short, void *), void *arg);
/*将event加入到event_base中*/
int
event_add(struct event *ev, const struct timeval *tv);
/*从event_base中删除event*/
int
event_del(struct event *ev);
/*事件循环*/
int
event_base_loop(struct event_base *base, int flags);
/*event_base 的循环中检测到事件发生后、对event的处理*/
static int
event_process_active(struct event_base *base);
2.2 event_base
event_base的主要结构为:
其中evsel指向eventop:
struct eventop {
const char *name;
void *(*init)(struct event_base *);
int (*add)(struct event_base *, evutil_socket_t fd, short old, short events, void *fdinfo);
int (*del)(struct event_base *, evutil_socket_t fd, short old, short events, void *fdinfo);
int (*dispatch)(struct event_base *, struct timeval *);
void (*dealloc)(struct event_base *);
int need_reinit;
enum event_method_feature features;
size_t fdinfo_len;
};
2.3 bufferevent
struct bufferevent *
bufferevent_socket_new(struct event_base *base, evutil_socket_t fd,
int options)
{
struct bufferevent_private *bufev_p;
struct bufferevent *bufev;
#ifdef _WIN32
if (base && event_base_get_iocp_(base))
return bufferevent_async_new_(base, fd, options);
#endif
if ((bufev_p = mm_calloc(1, sizeof(struct bufferevent_private)))== NULL)
return NULL;
if (bufferevent_init_common_(bufev_p, base, &bufferevent_ops_socket,
options) < 0) {
mm_free(bufev_p);
return NULL;
}
bufev = &bufev_p->bev;
evbuffer_set_flags(bufev->output, EVBUFFER_FLAG_DRAINS_TO_FD);
/*一个fd有多个事件 读 写 将该fd对应的读写事件注册到event_base中*/
event_assign(&bufev->ev_read, bufev->ev_base, fd,
EV_READ|EV_PERSIST|EV_FINALIZE, bufferevent_readcb, bufev);
event_assign(&bufev->ev_write, bufev->ev_base, fd,
EV_WRITE|EV_PERSIST|EV_FINALIZE, bufferevent_writecb, bufev);
evbuffer_add_cb(bufev->output, bufferevent_socket_outbuf_cb, bufev);
evbuffer_freeze(bufev->input, 0);
evbuffer_freeze(bufev->output, 1);
return bufev;
}
ssss