libevent 之epoll 观后感

libevent支持很多系统,因本人是做Linux后台的,故只看了epoll部分。

eventops 数组用来实现devpoll, kqueue, epoll, poll, select 实现的选择。

event_base * current_base; libevent 主要控制结构。

event_base 分3个队列 EVLIST_INSERTED, EVLIST_ACTIVE, EVLIST_TIMEROUT.

EVLIST_INSERTED 队列 保存 加入到event_base的所有event, 为什么要这个队列呢?

event.c中

/* reinitialized the event base after a fork */
int
event_reinit(struct event_base *base)

这个函数在fork 之后可以被调用,fork之后需要重新设置监听事件。

 

EVLIST_ACTIVE 分优先级的队列,不过默认是1个优先级(等于没有优先级)

EVLIST_TIMEROUT 是个数组,以超时组织的小端堆(删除,插入时间是lg(N))。

epoll.c

struct evepoll {
    struct event *evread;
    struct event *evwrite;
};

struct epollop {
    struct evepoll *fds;
    int nfds;
    struct epoll_event *events;
    int nevents;
    int epfd;
};

 

struct evepoll *fds; 有什么用?

struct evepoll {
    struct event *evread;
    struct event *evwrite;
}; 为什么要分读写?

原来libevent 支持一个fd 有两个 event对象的情形。

event r, w;

event_set(&r, fd, EV_READ,&r);

event_set(&w, fd, EV_WRITE,&r);

ev_read, ev_write 可以是不同的event, 也正因为fd可以有两个event, 所以不能放到 epoll_data_t中。(以前自己实现的时候就没有使用fd数组,因为所有的fd只有一个对用的控制结构)

struct evepoll *fds 是个数组,这带来极大的便利,通过fds[fd]就可以找到控制结构,这依赖于操作系统的特性(新fd总是系统中最小空闲fd.)


libevent 还可以延后处理signal,  通过一对unix套接字来唤醒epoll_wait,从而加速signal event的处理。

如果没有这样做的话,可能就要等到epoll_wait超时后才能调用,但epoll_wait的时间跟timer_out 队列的时间相关,

如果timer_out 队列为空,就更是糟糕。 

 

总结:

libevent 也有个小缺陷,就是不支持多线程,不过一般不是大问题,因为长时间任务,都要自己实现线程组和队列。

linux 现在支持 timerfd 和siganlfd, 不过其它系统可能不支持。

你可能感兴趣的:(libevent)