| |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
-> 系统运维 -> I/O 多路复用技术概述 -> 正文阅读 |
|
[系统运维]I/O 多路复用技术概述 |
最开始,传统的 socket 模型效率极差,下面我通过伪代码描述整个过程,服务端代码如下:
客户端代码如下:
整个处理流程如下所示:
上述流程很明显存在以下几个问题:
为了解决上述问题,通过多线程处理 socket 的方式诞生了,具体伪代码如下:
如上图所示,此时可以解决服务端无法处理多个客户端连接的问题,实现也很简单,每个客户端对应一个线程,在子线程中实现处理逻辑,主线程一直循环等待客户端连接。这样做的好处有以下几点:
虽然多线程 socket 模型可以同时处理多个客户端,但线程毕竟是珍贵资源,如果每个客户端都维护一个线程的话,开销太大,不能支持多客户端。而且它仍然没有解决 socket 模型效率低下的主要原因:I/O 操作阻塞太严重 read() 方法阻塞等待 I/O 处理导致 CPU 绝大多数时候处于等待的状态,为了充分利用 CPU 资源,操作系统内核提供了全新的、非阻塞的 read() 方法,只需在调用 read() 方法前将 socket 对应文件描述符设置为非阻塞状态即可,如果数据没到达直接返回 -1,无须阻塞等待 有了非阻塞的 read() 方法,整体逻辑又可以优化为这样:
有了非阻塞的 read() 方法可以提高 CPU 利用率,让线程不在阻塞,但它仍然没解决客户端连接线程一对一问题,至此终于到本篇的标题,I/O 多路复用技术 最开始的多路复用思路是这样的:一旦服务端建立连接,将对应 socket 的文件描述符放入数组中,创建一个线程无限遍历这个数组,依次调用 read() 方法,这样就可以通过一个线程处理多个连接,具体伪代码如下:
这种方式虽然能通过单个线程处理多个客户端连接,但效率只会更差,主要原因有两点:
总的来说,从应用程序角度是没法实现真正的多路复用技术的,因为无论你怎么处理,涉及到系统调用、阻塞这种操作系统内核维护的问题无法解决 到这里,第一代操作系统维护的多路复用技术产生了:select 系统调用,其中它的大体思路如下: 用户无须创建线程遍历文件描述符,而是将文件描述符数组发送给操作系统,让操作系统去遍历,确定哪个文件描述符可以读写,然后告诉我们去处理 select() 系统调用函数定义如下:
此时服务端逻辑可以优化为这样:
select 系统调用在收到文件描述符后,会在操作系统层面遍历所有描述符,在就绪的文件描述符做上标识,并返回就绪的个数 总得来说,select 具有以下缺点:
和上面提到的多路复用实现思路相比,select 只是省去上下文切换的消耗,不过文件描述符越多,提高的效率越多。按上面提到的思路,假设有 n 个描述符每轮循环就需要 n 次系统调用,就绪 m 个就需要再调用 m 次 read() 系统调用、使用 select 就可以节省为 1 次 select() 系统调用和 m 次就绪 read() 系统调用 后来内核又在 select 的基础上提出了 poll,poll 主要去掉 select 最多只能监听 1024 个文件描述符的上限,其它变化不大 最后,操作系统提出了 epoll,epoll 和 select/poll 采用完全不同的处理模式,并解决了很多 select/poll 没有实现的功能: 针对 select/poll 的缺点,epoll 分别做了如下改进:
其中 epoll 对外提供的方法如下:
最后简单总结一下:I/O 多路复用技术实际属于随着时代发展,业务量倒逼操作系统内核实现更多功能的过程,这些功能在应用程序中也可以实现,但就像上面说的那样,效率高不了。因为涉及到系统调用存在上下文切换的消耗,I/O 多路复用技术实际节省的也就是这部分上下文切换的损耗 参考:微信公众号《低并发编程》 |
|
|
上一篇文章 下一篇文章 查看所有文章 |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 | -2024/11/15 9:46:30- |
|
网站联系: qq:121756557 email:121756557@qq.com IT数码 |