当前位置: 首页 > 开发知识 >

linux系统中的异步IO模型select,poll,epoll

作者:游戏app开发公司 阅读: 发布时间:2024-08-23 10:01

摘要:#operations | poll | select | epoll10 | 0.61 | 0.7...

我们都知道linux的哲学是一切接文件,也就是说无论是我们的进程,线程,还是我们的设备,最后都对应的是文件,而文件操作就是linux的核心。那么linux中有几种操作输入输出的模型呢?答案是三种,就是select,poll,epoll。

_linux异步io模型_异步选择模型

select

这个模型是在1983年的unix系统中引入的,它通过fd_set变量来控制设备需要等待什么。也就是说linux中有个select函数,我们是通过它来监控文件状态的。

int select(int maxfdp1, fd_set *readset, fd_set *writeset, fd_set *exceptset,struct timeval *timeout);

(1)intmaxfdp是一个整数值,是指集合中所有文件描述符的范围,即所有文件描述符的最大值加1,不能错。

说明:对于这个原理的解释可以看上边fd_set的详细解释,fd_set是以位图的形式来存储这些文件描述符。maxfdp也就是定义了位图中有效的位的个数。

(2)fd_set*readfds是指向fd_set结构的指针,这个集合中应该包括文件描述符,我们是要监视这些文件描述符的读变化的,即我们关心是否可以从这些文件中读取数据了,如果这个集合中有一个文件可读,select就会返回一个大于0的值,表示有文件可读;如果没有可读的文件,则根据timeout参数再判断是否超时,若超出timeout的时间,select返回0,若发生错误返回负值。可以传入NULL值,表示不关心任何文件的读变化。

(3)fd_set*writefds是指向fd_set结构的指针,这个集合中应该包括文件描述符,我们是要监视这些文件描述符的写变化的,即我们关心是否可以向这些文件中写入数据了,如果这个集合中有一个文件可写,select就会返回一个大于0的值,表示有文件可写,如果没有可写的文件,则根据timeout参数再判断是否超时,若超出timeout的时间,select返回0,若发生错误返回负值。可以传入NULL值,表示不关心任何文件的写变化。

(4)fd_set*errorfds同上面两个参数的意图,用来监视文件错误异常文件。

(5)structtimeval* timeout是select的超时时间,这个参数至关重要,它可以使select处于三种状态,第一,若将NULL以形参传入,即不传入时间结构,就是将select置于阻塞状态,一定等到监视文件描述符集合中某个文件描述符发生变化为止;第三,若将时间值设为0秒0毫秒,就变成一个纯粹的非阻塞函数,不管文件描述符是否有变化,都立刻返回继续执行,文件无变化返回0,有变化返回一个正值;第三,timeout的值大于0,这就是等待的超时时间,即 select在timeout时间内阻塞,超时时间之内有事件到来就返回了,否则在超时后不管怎样一定返回,返回值同上述。

poll

poll在1986年引入unix中,在linux中是在1997年引入的。它的函数定义为:

int poll ( struct pollfd * fds, unsigned int nfds, int timeout);

fds:是一个struct pollfd结构类型的数组,用于存放需要检测其状态的Socket描述符;每当调用这个函数之后,系统不会清空这个数组,操作起来比较方便;特别是对于socket连接比较多的情况下,在一定程度上可以提高处理的效率;这一点与select()函数不同,调用select()函数之后,select()函数会清空它所检测的socket描述符集合,导致每次调用select()之前都必须把socket描述符重新加入到待检测的集合中;因此,select()函数适合于只检测一个socket描述符的情况,而poll()函数适合于大量socket描述符的情况;

异步选择模型__linux异步io模型

epoll

epoll是在linux2.5内核中引入的,目前是比poll和select模型都要高效。epoll实现主要实现三个接口。

int epoll_create(int size);

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

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

首先,调用epoll_create建立一个epoll对象。参数size是内核保证能够正确处理的最大句柄数。

然后,epoll_ctl可以操作上面建立的epoll,例如,将刚建立的socket加入到epoll中让其监控,或者把 epoll正在监控的某个socket句并移出epoll,不再监控它等等。

最后,epoll_wait在调用时,在给定的timeout时间内,当在监控的所有句柄中有事件发生时,就返回用户态的进程。

epoll提供两种触发模式,一种水平触发,一种边缘触发。

水平触发:就是只有高电平(1)或低电平(0)时才触发通知,只要在这两种状态就能得到通知。

边缘触发:只有电平发生变化(高电平到低电平,或者低电平到高电平)的时候才触发通知。

简单理解,在水平触发的时候,可以时刻监测IO的状态,而边缘触发,只有下次IO活动到来的时候,才进行通知。因此,当监视数量描述符多的时候,边缘触发的epoll效率更高。

# operations  |  poll  |  select   | epoll
10            |   0.61 |    0.73   | 0.41
100           |   2.9  |    3.0    | 0.42
1000          |  35    |   35      | 0.53
10000         | 990    |  930      | 0.66

总结

异步选择模型_linux异步io模型_

epoll采用基于事件的就绪通知方式。在select/poll中,进程只有在调用一定的方法后,内核才对所有监视的文件描述符进行扫描,而epoll事先通过epoll_ctl()来注册一个文件描述符,一旦基于某个文件描述符就绪时,内核会采用类似callback的回调机制,迅速激活这个文件描述符,当进程调用epoll_wait()时便得到通知。

  • 原标题:linux系统中的异步IO模型select,poll,epoll

  • 本文由游戏app开发公司小编,整理排版发布,转载请注明出处。部分文章图片来源于网络,如有侵权,请与迪集网络联系删除。
  • 微信二维码

    CLWL6868

    长按复制微信号,添加好友

    微信联系

    在线咨询

    点击这里给我发消息QQ客服专员

    点击这里给我发消息电话客服专员

    在线咨询

    免费通话


    24h咨询☎️:132-5572-7217


    🔺🔺 24小时客服热线电话 🔺🔺

    免费通话
    返回顶部