I/O多路复用总结

select

#incl_ude <sys/select. h>
#include <sys/time.h>
int select(int maxfd, fd_set * readset, fd_set * writeset, 
                      fd_set * exceptset, const struct timeval * timeout);
//成功时返回大千0 的值,失败时返回-1 。
 
#maxfd 是一个整数值,是指集合中所有文件描述符的范围,即所有文件描述符的最大值加1,不能错。
#readset 将所有关注“是否存在待读取数据”的文件描述符注册到fd_set型变量,并传递其地址值。
#writeset 将所有关注“是否可传输无阻塞数据”的文件描述符注册到fd_set型变量,并传递其地址值。
#exceptset 将所有关注”是否发生异常"的文件描述符注册到fd_set型变量,并传递其地址值。
#timeout 调用select 函数后,为防止陷入无限阻塞的状态,传递超时( time-out ) 信息。
#返回值 发生错误时返回-1, 超时返回时返回0。因发生关注的事件返回时,返回大千0的值,该值是发生事件的
文件描述符数。

优点

  • 服务器端接入者少。
  • 程序应具有兼容性。

缺点:

  • 调用select函数后,需要对所有文件描述符执行循环检查语句。
  • 每次调用select函数时都需要向该函数传递监视对象信息。
  • 监视的fd数量被限制,32位机默认是1024个,64位机默认是2048。

参考:https://blog.csdn.net/qq_40732350/article/details/88978584

 

pselect

int pselect(int                    maxfdp1,
            fd_set                *readfds,
            fd_set                *writefds,
            fd_set                *exceptfds,
            const struct timespec *tsptr,
            const sigset_t        *sigmask);

优点:

  • pselect的超出时间能指定到纳秒级(旧结构只能指定到微秒级)
  • pselect增加了指向信号集的指针sigmask(此时的信号集表示信号掩码)

pselect函数是一个 防止信号干扰的增强型 select函数(重点啊小哥们)

对于pselect可使用一可选择的信号屏蔽字。若sigmask为空,那么在与信号有关的方面,pselect的运行状况和select相同。否则,sigmask指向一信号屏蔽字,在调用pselect时,以原子操作的方式安装该信号屏蔽字。在返回时恢复以前的信号屏蔽字。

 

 

 

poll

int poll(struct pollfd fds[], nfds_t nfds, int timeout);
#fds是一个指向结构pollfd数组的指针,监视的文件描述符和条件放在里面。
#nfds是比监视的最大描述符的值大1的值。
#timeout是超时时间,单位为毫秒,当为负值时,表示永远等待。

大于0:表示满足条件的文件描述符数量
    0:超时
   -1:发生错误

缺点:

  • 大量的fd的数组被整体复制于用户态和内核地址空间之间,而不管这样的复制是不是有意义。                   
  • poll还有一个特点是“水平触发”,如果报告了fd后,没有被处理,那么下次poll时会再次报告该fd。

poll和select的区别

poll库与 select库的主要区别在于, select库需要为读事件、写事件和异常事件分别创建一个描述符集合,因此在最后轮询的时候,需要分别轮询这三个集合,而poll库只需要创建一个集合,在每个描述符对应的结构上分别设置读事件,写事件或异常事件,最后轮询的时候可以同时检查这三种事件是否发生,poll是select的优化实现。

 

 

 

epoll

#include <sys/epoll. h>
int epoll_wait(int epfd, struct epoll_event * events, int maxevents, int timeout);
//成功时返回发生事件的文件描述符数,失败时返回-1。
 
#epfd      表示事件发生监视范围的epoll例程的文件描述符。
#events    保存发生事件的文件描述符集合的结构体地址值。
#maxevents 第二个参数中可以保存的最大事件数。
#timeout   以1/1000秒为单位的等待时间,传递-1 时, 一直等待直到发生事件。

优点:

  • 同时可以返回多个文件描述符变化的事件。
  • 以事件的形式返回文件描述符的变化。
  • 内存拷贝,利用mmap()文件映射内存加速与内核空间的消息传递;即epoll使用mmap减少复制开销。

缺点:

  • 是Linux所特有的,所以移植性不够好。

 

边缘触发比条件触发的好处

  • 条件触发关心的是事件状态:只要处在某个状态下就会一直触发事件
  • 条件触发关心的是事件状态改变:只要状态发生改变就会触发事件

 

 

 

 

参考:https://blog.csdn.net/qq_40732350/article/details/89021711

 

select、poll、epoll 区别总结:

 进程的最大连接数FD剧增后带来的IO效率问题消息传递方式
select会受到宏的限制因为每次调用时都会对连接进行线性遍历,所以随着FD的增加会造成遍历速度慢的“线性下降性能问题”。内核需要将消息传递到用户空间,都需要内核拷贝动作
poll系统运行打开的最大数目同上同上
epoll系统运行打开的最大数目因为epoll内核中实现是根据每个fd上的callback函数来实现的,只有活跃的socket才会主动调用callback,所以在活跃socket较少的情况下,使用epoll没有前面两者的线性下降的性能问题,但是所有socket都很活跃的情况下,可能会有性能问题。epoll通过内核和用户空间共享一块内存来实现的。

epoll不是采用轮询,所以时间复杂度是O(1);

select() 提供了更高的超时精度:select() 支持微秒级,poll() 支持毫秒级。ppoll() 和 pselect() 理论上都提供了纳秒级的超时精度,但是实际上,这两个调用的毫秒级精度都不可靠。

 selectpollepoll
监控单元文件描述符集合结构体数组需要监控的结构体
工作模式条件触发条件触发条件触发/边缘触发
实现方式轮询轮询回调机制
数据传递  mmap内存映射
应用平台无关,监控数量少只使用于Linux,监控数量少只使用于Linux,可以监控大量的文件描述符

 

 

 

参考:https://www.cnblogs.com/zhaodahai/p/6831456.html

 

 

 

 

 

 

 

 

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值