三种IO多路复用机制介绍

select 

select:开始是1983年的时候出现在4.2BSD中,用select可以让程序监视多个文件句柄(file descriptor)的状态,当被监视的文件句柄有某一个或多个发生状态改变时,返回的数组中就绪的文件描述符便会被内核修改标志位,使得进程可以获得这些文件描述符从而进行后续的读写操作。

select的优点:
1.具有良好跨平台支持,几乎在所有的平台上支持。

select的缺点:
1.在单个进程能够监视的文件描述符的数量存在最大限制,在Linux上一般为1024,需要可以通过修改宏定义甚至重新编译内核的方式提升这一限制;
2.采用轮询数组的方式线性扫描文件描述符,文件描述符数量越多,性能越差;

API介绍
int select (int maxfd,fd_set *readset,fd_set *writeset,fd_set *exceptset,struct timeval *timeout);
maxfd: 监视最大文件描述符数量;
readset:可读的文件描述符集合;
writeset:可读的文件描述符集合;
exceptset:出现异常的文件描述符集合;
timeout: 超时时间,timeout == NULL表示等待无限长的时间;
返回值:错误返回-1,超时返回0。返回值大于0时,该值是发生事件的文件描述符个数。

poll 
poll开始是在1986年的System V Release 3中出现,它和select在本质上没有多大差别,但由于poll是基于链表来存储,所以没有最大文件描述符数量的限制。

API介绍
int poll(struct pollfd *fdarray, unsigned long nfds, int timeout);
fdarray:     一个结构体,用来保存各个描述符的相关状态;
nfds: 要监视的描述符的数目;
timeout:         超时时间(-1:永远等待;0:立即返回;>0:等待的毫秒数);
返回值:          错误返回-1,超时返回0。返回值大于0时,该值是发生事件的文件描述符数。

像select()和poll()这种将就绪的文件描述符告诉进程后,如果进程没有对其进行IO操作,那么下次调用select()和poll()的时候将再次报告这些文件描述符,所以一般不会丢失就绪的消息,这种方式称为水平触发(Level Triggered)。
只告诉进程哪些文件描述符刚刚变为就绪状态,只说一遍,如果我们没有采取行动,那么它将不会再次告知,这种方式称为边缘触发(Edge Triggered),理论上边缘触发的性能要更高一些,但是代码实现相当复杂。。

epoll 
epoll:开始是在2002的Linux2.5.44中支持的实现方法,它几乎具备了select和epoll的一切优点,被公认为Linux2.6下性能最好的多路I/O就绪通知方法。

epoll的使用需要用到epoll_create,epoll_ctl,epoll_wait

1.创建一个epoll的句柄:
int epoll_create(int size); 

2.epoll的事件注册函数
int epoll_ctl(int epfd, int op, int fd, struct epoll_event *event);
epfd: epoll_create创建之后的句柄
op: 事件处理的类型
fd: 需要监听的fd
event: 告诉内核需要监听哪种类型的事件

3.等待直到注册的事件发生
int epoll_wait(int epfd, struct epoll_event * events, int maxevents, int timeout);
epfd: epoll_create创建之后的句柄
events: 注册的所有的读写事件
maxevents: 最大事件数(不能大于创建epoll_create()时的size)
timeout: 超时时间(0,立即返回,-1永久阻塞,>0:等待的毫秒数)

epoll工作模式有两种:LT和ET(在epoll_ctl的epoll_event参数中指定,LT模式是默认模式):

  区别如下:

  LT模式:当epoll_wait检测到描述符事件发生时将此事件通知应用程序,应用程序可以不立即处理该事件,如果不处理,下次epoll_wait调用时会,再次通知该事件。

  ET模式:当epoll_wait检测到描述符事件发生时将此事件通知应用程序,应用程序需要立即处理该事件,如果不处理,下次epoll_wait调用时会,不会通知该事件。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值