欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

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

程序员文章站 2024-02-01 16:35:04
...

最近需要使用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。

 

 

 

 

相关标签: epoll