I/O 多路复用:select/poll/epoll详解

I/O 多路复用:select/poll/epoll

概述

I/O多路复用是一种使得程序能够同时监听多个文件描述符的技术,从而提高程序的性能。select/poll/epoll 是Linux下实现I/O复用的系统调用。

文件描述符(file descriptor)

是内核为了高效管理已被打开的文件所创建的索引,用于指向被打开的文件,所有的I/O操作的系统调用都会通过文件描述符。

在Linux操作系统中,每一个进程都对应着一个文件描述符表,对应一个数组指针,默认前三位分别为标准的输入流(键盘),标准的输出流(显示器),标准的错误流(显示器)。如果随后进程创建了一个Socket,那么这个文件描述符表的低四位就是指向这个socket的指针。

在Linux操作系统中,一切皆文件。

Socket连接

双方进行网络通信之前,各自都会创建一个Socket。Socket 实际上是一个文件,也就会对应一个文件描述符。在 Linux 下,单个进程打开的文件描述符数是有限制的,没有经过修改的值一般都是 1024,不过我们可以通过 ulimit 增大文件描述符的数目;

Socket是应用层与TCP/IP协议族通信的中间软件抽象层,它是一组接口(API)。我们所说的TCP/IP协议栈是在操作系统内核实现的,而Socket就是操作系统内核提供给应用层的一系列接口,Socket封装了TCP/IP,要使用TCP/IP来发送数据,就调用Socket的OutputStream,要使用TCP/IP接收数据,就调用Socket的InputStream。

在这里插入图片描述

IO复用

IO复用的历史和多进程一样长,Linux很早就提供了select系统调用,可以在一个进程内维护1024个连接,后来加入poll系统调用,poll做了一系列改进后解决了1024个连接的限制问题,可以维持任意数量的连接。

一个进程任意时刻只能处理一个请求,但是如果耗时很短,这样短时间内就可以处理大量的请求,和并发类似,多个请求复用一个进程,这就是多路复用。

select

select将已经连接的Socket都放在一个文件描述符集合中,然后调用select函数将其拷贝到内核中,内核再检验是否有网络IO事件的发生,当检查到有事件发生后,将Socket标记为可读或可写,再把文件描述符集合拷贝回用户态,用户态再通过遍历的方法找到可读或可写的Socket。

在这里插入图片描述

select需要进行两次遍历和拷贝,一个进程最多维护1024个文件描述符。

poll

poll和select并没有本质上的区别,区别在于poll不再使用BitMap来存储文件描述符,转而使用动态数组,以链表的形式来存储文件描述符,突破了select1024的数量限制。

epoll

1.epoll在内核中使用了红黑树的数据结构来跟踪所有待检测的文件描述符,时间复杂度降为o(logn)。每次只需要传入一个待检测的socket,该socket会与相应的设备建立回调关系,相应的事件发生后,就会调用这个函数。

2.epoll使用事件驱动的机制,内核中维护了一个链表来记录就绪事件,当socket有事件发生时,通过回调函数内核将其加入就绪事件列表中,系统调用epoll_wait()函数时,会返回事件发生的文件描述符,不会再像poll和select一样遍历扫描。当数十万并发连接存在时,可能每一毫秒只有几十个活跃的连接,这时select的效率就会显著低于epoll。

在这里插入图片描述

边沿触发和水平触发

边沿触发:当被监控的socket描述符上有可读事件发生时,服务器只会从epoll_wait中苏醒一次。

水平触发:服务器会不断地从epoll_wait中苏醒,直到内核缓冲区的数据被read函数读完才结束

参考文章链接

https://xiaolincoding.com/os/8_network_system/selete_poll_epoll.html#%E5%A4%9A%E8%BF%9B%E7%A8%8B%E6%A8%A1%E5%9E%8B

https://www.cnblogs.com/python8/p/15395970.html

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值