linux高性能服务器编程笔记 第9章I/O复用

2020.05.15

三种常见I/O复用函数比较

#include<sys/select.h>
int select(int fds, fd_set *readfds, fd_set *writefds, fd_set *exceptionfds, struct timeval *temiout);
//nfds指定被监听的文件描述符总数,通常被设置为select监听的文件描述符的最大值+1;
//readfds,writefds,exceptfds分别指可读、可写、异常等事件对应的文件描述符集合,通过这三个参数传入感兴趣的文件描述符,select返回时,内核将修改它们来通知应用程序那些文件描述符已就绪

#include<poll.h>
int poll(struct pollfd *fds, nfds_t nfds, int temeout);
struct pollfd{
	int fd;			//文件描述符
	short events;	//注册时间
	short revents;	//实际发生的事件,由内核填充
};
//fds指定感兴趣的文件描述符上发生的可读、可写、异常事件
//nfds指定被监听事件集合fds的大小

#include<sys/epoll.h>
int epoll_create(int size);
int epoll_ctl(int epfd, int op, int fd, struct epoll_event *event);
struct epoll_event{
	__uint32_t events;
	epoll_data_t data;
};
typedef union epoll_data{
	void *ptr;
	int fd;
	uint32_t u32;
	uint64_t u64;
}epoll_data_t;
//根据参数op,对epfd所标识的epoll时间表进行事件注册、修改、删除
int epoll_wait(int eplfd, struct epoll_event *events, int maxevents, int timeout);
  • 事件集对比
  1. select并没有将事件与文件描述符绑定,因此select需要三个fd_set类型的参数来分别传入和输出可读、可写、异常事件,这使得select不能处理更多类型的事件;另一方面由于内核直接对fd_set进行修改,应用程序在下次调用select前不得不重置fd_set;
  2. poll的参数pollfd同时把文件描述符和事件定义在其中,使得任何事件被统一处理;而且内核修改的是revents成员,是的应用程序不需重置事件集合;
  3. epoll不同于select和poll,epoll通过在内核注册一个事件表,通过独立函数epoll_ctl来管理事件表,每次epoll_wait调用都将直接从内核事件表中取得用户注册的事件,而无需反复的从用户空间读入这些事件。

由于每次select和poll调用都返回整个用户注册的事件集合,所以每次应用程序索引就绪文件描述符的时间复杂度都为O(n),而epoll_wait调用的events参数仅用来返回就绪的事件,使得应用程序索引就绪文件描述符的复杂度达到O(1)。

  • 最大支持文件描述符数
  1. select允许监听的最大文件描述符有限,虽然用户可以修改,但是会导致不可预期的结果;
  2. poll和epoll分别使用nfds和maxevents指定最多监听多少个文件描述符和事件,两个参数的最大值都是65535,16位。
  • 工作模式
    select和poll只支持相对低效的LT模式,而epoll支持ET模式,而且epoll还支持EPOLLONESHOT事件,可以进一步减少可读、可写、异常等时间被触发的次数;

  • 实现原理

  1. select和poll都采用轮询的方式,每次调用都要扫描整个注册文件描述符集合,并将其中就绪的返回给用户程序,因此其检测就绪事件的复杂度是O(n);
  2. epoll采用回调的方式,内核检测到就绪的文件描述符时,将触发回调函数,回调函数就将该文件描述符上对应的事件插入内核就绪事件队列。内核最后在适当的时机将就绪队列中的内容拷贝到用户空间,而epoll_wait无须轮询整个文件描述符集合来检测那些事件已经就绪,其时间复杂度是O(1)。

但是当活动链接较多时,epoll_wait的效率不一定比select和poll高,因为此时回调函数被触发得过于频繁,所以epoll_wait适用于;连接数量多,但活动链接数量少的情况。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值