Linux网络:多路转接epoll

目录

一、epoll函数及相关系统调用

1.1epoll的相关系统调用

 epoll_create:

 epoll_ctl:

 epoll_wait

二、epoll的优点


一、epoll函数及相关系统调用

博主之前的博文中详细介绍了poll和select的功能及使用方法,而本文所介绍的epoll根据Linux中man手册的说法是为处理大批量句柄而作了改进的 poll

1.1epoll的相关系统调用

 epoll_create:

int epoll_create(int size);

创建一个 epoll 的句柄。

linux2.6.8 之后,size 参数是被忽略的。

用完之后, 必须调用 close()关闭。

 epoll_ctl:

注册epoll要监视的事件

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

不同于select()是在监听事件时直接告诉内核要监听什么类型的事件, 而是在这里先注册要监听的事件类型。

第一个参数是epoll_create()的返回值(epoll的句柄)。

第二个参数表示动作,也就是拿着fd对epfd做修改,用三个宏来表示。

第三个参数是需要监听的 fd 对象。

第四个参数是告诉系统内核需要具体监听什么事。

 参数二的取值:

EPOLL_CTL_ADD:注册新的 fd 到 epfd 中;

EPOLL_CTL_MOD:修改已经注册的 fd 的监听事件;

EPOLL_CTL_DEL:从 epfd 中删除一个 fd;

 参数四struct epoll_event结构:

typedef union epoll_data
{
    void* ptr;
    int fd;
    uint32_t u32;
    uint64_t u64;
}epoll_data_t;
struct epoll_event
{
    uint32_t
events;
    epoll_data_t
data;
}__EPOLL_PACKED;

events可以作为以下宏的集合:

EPOLLIN : 表示对应的文件描述符可读 (包括对端 SOCKET 正常关闭的情况);

EPOLLOUT : 表示对应的文件描述符可写;

EPOLLPRI : 表示对应的文件描述符有紧急的数据可读 (这里应该表示有带外数据的到来);

EPOLLERR : 表示对应的文件描述符发生了错误;

EPOLLHUP : 表示对应的文件描述符被挂断;

EPOLLET : 将 EPOLL 设为边缘触发模式, 这是相对于水平触发来说的。

EPOLLONESHOT:只监听一次事件, 当监听完这次事件之后, 如果还需要继续监听这个 socket 的话, 需要再次把这个 socket 加入到 EPOLL 队列里。

 epoll_wait

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

收集在 epoll 监控的事件中已经发送的事件。

1、参数 events 是已经分配好的 epoll_event 结构体数组。

2、epoll 将会把发生的事件赋值到 events 数组当中(events 不可以是nullptr空指针,内核只负责把数据拷贝到 events 数组中,不会帮助我们在用户态中分配开辟内存)

3、maxevents 告诉内核这个 events 数组有多大,maxevents 的值不能大于创epoll_create()时的 size。

4、参数 timeout 是超时时间 (毫秒,0 会立即返回,-1则是 永久阻塞)

函数调用成功时,返回I/O上已经准备就绪的文件描述符的数目,返回0表示已经超时没有就绪,返回小于0表示函数失败了。 

二、epoll的优点

1、接口使用更加方便: 虽然将整个epoll拆分成了三个函数, 但是反而使用起来更加高效. 不需要每次循环的去设置关注的文件描述符, 也做到了输入输出参数可以分离开

2、数据拷贝轻量: 只在合适的时候调用 EPOLL_CTL_ADD 将文件描述符结构拷贝到内核中, 这个操作并不频繁(而 select/poll 都是每次循环都要进行拷贝)

3、事件回调机制: 避免使用遍历的方法, 而是使用回调函数的方式, 将已经就绪的文件描述符 结构添加到就绪队列当中, epoll_wait 返回直接访问就绪队列就可以知道哪些文件描述符已经就绪。这个操作时间复杂度 O(1)。即使文件描述符数目很多, 效率也不会受到影响

 4、没有数量限制: 文件描述符数目无上限

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

C+五条

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值