`

Epoll 轮询机制 和libevent的多线程实现

阅读更多

最近需要使用Linux开发,需要在网络连接上复用。原有程序是使用每个请求进行一次创建线程,执行事务,销毁线程,这种模式来实现多个请求。现在希望能够基于线程池实现请求复用。实际上效果应该不会太好,因为:

  1. 请求都是内部高速Lan连接
  2. 单台服务器请求数不会超过500
  3. 属于CPU计算密集型;I/O较少。因此,主要耗时,还是服务本身,平均100ms/每核;假设线程创建销毁1ms,那么这1%即使完全节省下来,也不会有提高。
  4. epoll模型和select模型。理论上,此时epoll不会比select高效,理由Lan高速连接,连接都是Active而不是wait。当然,无论选择哪种,都不会提升服务质量,理由3

不管怎样,继续学习epoll的使用。

epoll用于Linux2.6上,主要用于处理高并发连接。

epoll 有3个函数:epoll_create,epoll_ctl,epoll_wait

外加一个用于关闭句柄的 close函数;1个对象struct epoll_event。

 

 

创建句柄(Handle)

int handle = epoll_create(int size);

返回的是一个句柄,这个句柄最后是需要close的(所有句柄,都需要close,无论windows还是linux,句柄实际上是一个内核对象)。

 

size表明可监听的并发连接数目,在Linux2.6.8以后,该参数被忽略,仅仅向下兼容考虑。

 

注册事件

int epoll_ctl(int epfd,int op,int fd,struct epoll_event *event);

 

epfd,创建时候的句柄

op,operation的意思,表示执行何种命令,

EPOLL_CTL_ADD;增加

EPOLL_CTL_MOD:修改

EPOLL_CTL_DEL:删除

常见的增删改(不包含查询,实际内部需要使用查询)

 

//常见的如果存在就修改,否则增加,Redis中有如下源码

    int op = eventLoop->events[fd].mask == AE_NONE ?
            EPOLL_CTL_ADD : EPOLL_CTL_MOD;

 

struct epoll_event{

__uint32 events;//epoll事件类型

epoll_data_t data;//用户数据

};

 

EPOLLIN:触发该事件,有可读数据。(包括对端SOCKET正常关闭);
EPOLLOUT:触发该事件,有可以写数据;
EPOLLPRI:紧急数据处理(可读),urgent data available for read

EPOLLERR:发生错误;
EPOLLHUP:暂时被挂断;
EPOLLET: ET模式

EPOLLONESHOT:   只监听一次事件,用完即结束。

 

等待事件

int epoll_wait(int epfd, struct epoll_event * events, int maxevents, int timeout)

 

Epoll是支持多线程的,即多个线程都可以监听各自的epoll,而这些Epoll都监听同一端口,而不用担心惊群。

 

  • libevent中的多线程实现

由于libevent的event base

实现方式:2种

  1. 类似于memcache的实现,即一个masert,通过管道pipie与子线程通信。其实这个类似于nginx的方式
  2. 因为,epoll是可以多线程安全的。因此,每个线程创建一个event base,然后关联同一个端口的fd。

 

 

 

 

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics