Linux IO 多路复用是什么意思?
写在前面:本文整理于知乎,原文链接为http://www.zhihu.com/question/32163005/answer/55772739,作者:罗志宇
再次向作者表示感谢~~
假设你是一个机场的空管, 你须要管理到你机场的全部的航线。 包含进港,出港, 有些航班须要放到停机坪等待,有些航班须要去登机口接乘客。
你会怎么做?
那么问题就来了:
非常快你就发现空管塔里面聚集起来一大票的空管员,交通略微繁忙一点,新的空管员就已经挤不进来了。
空管员之间须要协调,屋子里面就1, 2个人的时候还好,几十号人以后 。基本上就成菜市场了。
空管员常常须要更新一些公用的东西。比方起飞显示屏,比方下一个小时后的出港排期。最后你会非常惊奇的发现,每个人的时间最后都花在了抢这些资源上。
现实上我们的空管同一时候管几十架飞机稀松寻常的事情, 他们怎么做的呢?
他们用这个东西

这个东西叫flight progress strip. 每个块代表一个航班,不同的槽代表不同的状态,然后一个空管员能够管理一组这种块(一组航班),而他的工作。就是在航班信息有新的更新的时候。把相应的块放到不同的槽子里面。
这个东西如今还没有淘汰哦,仅仅是变成电子的了而已。
。
是不是认为一下子效率高了非常多,一个空管塔里能够调度的航线能够是前一种方法的几倍到几十倍。
假设你把每个航线当成一个Sock(I/O 流), 空管当成你的服务端Sock管理代码的话.
第一种方法就是最传统的多进程并发模型 (每进来一个新的I/O流会分配一个新的进程管理。)
另外一种方法就是I/O多路复用 (单个线程,通过记录跟踪每个I/O流(sock)的状态,来同一时候管理多个I/O流 。
)
事实上“I/O多路复用”这个坑爹翻译可能是这个概念在中文里面如此难理解的原因。所谓的I/O多路复用在英文中事实上叫 I/O multiplexing. 假设你搜索multiplexing啥意思,基本上都会出这个图:
于是大部分人都直接联想到”一根网线。多个sock复用” 这个概念,包含上面的几个回答。 事实上无论你用多进程还是I/O多路复用。 网线都仅仅有一根好伐。多个Sock复用一根网线这个功能是在内核+驱动层实现的。
重要的事情再说一遍: I/O multiplexing 这里面的 multiplexing 指的事实上是在单个线程通过记录跟踪每个Sock(I/O流)的状态(相应空管塔里面的Fight progress strip槽)来同一时候管理多个I/O流. 发明它的原因,是尽量多的提高server的吞吐能力。
是不是听起来好拗口,看个图就懂了.
在同一个线程里面, 通过拨开关的方式。来同一时候传输多个I/O流。 (学过EE的人如今能够站出来义正严辞说这个叫“时分复用”了)。
什么,你还没有搞懂“一个请求到来了,nginx使用epoll接收请求的过程是如何的”。 多看看这个图就了解了。
提醒下,ngnix会有非常多链接进来, epoll会把他们都监视起来,然后像拨开关一样。谁有数据就拨向谁。然后调用相应的代码处理。
------------------------------------------
了解这个主要的概念以后,其它的就非常好解释了。
select, poll, epoll 都是I/O多路复用的详细的实现。之所以有这三个鬼存在,事实上是他们出现是有先后顺序的。
I/O多路复用这个概念被提出来以后。 select是第一个实现 (1983 左右在BSD里面实现的)。
select 被实现以后,非常快就暴露出了非常多问题。
select 会改动传入的參数数组。这个对于一个须要调用非常多次的函数,是非常不友好的。
select 假设不论什么一个sock(I/O stream)出现了数据,select 仅仅会返回,但是并不会告诉你是那个sock上有数据,于是你仅仅能自己一个一个的找,10几个sock可能还好。要是几万的sock每次都找一遍,这个无谓的开销就颇有海天盛筵的豪气了。
select 仅仅能监视1024个链接。 这个跟草榴没啥关系哦。linux 定义在头文件里的,參见FD_SETSIZE。
select 不是线程安全的,假设你把一个sock增加到select, 然后突然另外一个线程发现。尼玛。这个sock不用。要收回。对不起。这个select 不支持的,假设你丧心病狂的居然关掉这个sock, select的标准行为是。。
呃。。不可预測的, 这个但是写在文档中的哦.
“If a file descriptor being monitored by select() is closed in another thread, the result is unspecified”
霸不霸气
于是14年以后(1997年)一帮人又实现了poll, poll 修复了select的非常多问题,比方
poll 去掉了1024个链接的限制,于是要多少链接呢, 主人你开心就好。
poll 从设计上来说。不再改动传入数组,只是这个要看你的平台了,所以行走江湖。还是小心为妙。
事实上拖14年那么久也不是效率问题, 而是那个时代的硬件实在太弱,一台server处理1千多个链接简直就是神一样的存在了,select非常长段时间已经满足需求。
但是poll仍然不是线程安全的, 这就意味着,无论server有多强悍。你也仅仅能在一个线程里面处理一组I/O流。你当然能够那多进程来配合了,只是然后你就有了多进程的各种问题。
于是5年以后, 在2002, 大神 Davide Libenzi 实现了epoll.
epoll 能够说是I/O 多路复用最新的一个实现,epoll 修复了poll 和select绝大部分问题, 比方:
epoll 如今是线程安全的。
epoll 如今不仅告诉你sock组里面数据,还会告诉你详细哪个sock有数据,你不用自己去找了。
epoll 当年的patch,如今还在,以下链接能够看得到:
/dev/epoll Home Page
贴一张霸气的图。看看当年神一样的性能(測试代码都是死链了。 假设有人能够刨坟找出来。能够研究下细节怎么測的).
横轴Dead connections 就是链接数的意思。叫这个名字仅仅是它的測试工具叫deadcon. 纵轴是每秒处理请求的数量,你能够看到。epoll每秒处理请求的数量基本不会随着链接变多而下降的。poll 和/dev/poll 就非常慘了。
但是epoll 有个致命的缺点。
。仅仅有linux支持。
比方BSD上面相应的实现是kqueue。
事实上有些国内知名厂商把epoll从安卓里面裁掉这种脑残的事情我会主动告诉你嘛。
什么,你说没人用安卓做server。尼玛你是看不起p2p软件了啦。
而ngnix 的设计原则里面, 它会使用目标平台上面最高效的I/O多路复用模型咯,所以才会有这个设置。普通情况下,假设可能的话,尽量都用epoll/kqueue吧。
详细的在这里:
Connection processing methods
PS: 上面全部这些比較分析。都建立在大并发以下。假设你的并发数太少,用哪个,事实上都没有差别。
假设像是在欧朋数据中心里面的转码server那种动不动就是几万几十万的并发,不用epoll我能够直接去撞墙了。
作者:罗志宇
链接:http://www.zhihu.com/question/32163005/answer/55772739
来源:知乎
著作权归作者全部。商业转载请联系作者获得授权,非商业转载请注明出处。
Linux IO 多路复用是什么意思?的更多相关文章
- 【知乎网】Linux IO 多路复用 是什么意思?
提问一: Linux IO多路复用有 epoll, poll, select,知道epoll性能比其他几者要好.也在网上查了一下这几者的区别,表示没有弄明白. IO多路复用是什么意思,在实际的应用中是 ...
- Linux IO多路复用 poll
Linux IO多路复用 poll 之前曾经提到过 select poll 跟select类似,poll改进了select的一个确定,就是poll没有监听上限 不过poll还是需要遍历以及频繁的把数组 ...
- Linux IO多路复用 select
Linux IO多路复用 select 之前曾经写过简单的服务器,服务器是用多线程阻塞,客户端每一帧是用非阻塞实现的 后来发现select可以用来多路IO复用,就是说可以把服务器这么多线程放在一个线程 ...
- Linux IO多路复用
监听文件描述符的状态来进行相应的读写操作,3个函数: 123 selectpollepoll 123456789 int (int nfds, fd_set *readfds, fd_set *wri ...
- Linux IO多路复用之epoll网络编程及源码(转)
原文: 前言 本章节是用基本的Linux基本函数加上epoll调用编写一个完整的服务器和客户端例子,可在Linux上运行,客户端和服务端的功能如下: 客户端从标准输入读入一行,发送到服务端 服务端从网 ...
- linux IO多路复用POLL机制深入分析
POLL机制的作用这里就不进行介绍,根据linux man手册,解释为在一个文件描述符上等待某个事件.按照抽象一点的理解,当某个事件被触发(条件被满足),文件描述符变为有状态,那么用户空间可以根据此进 ...
- Linux IO多路复用之epoll网络编程(含源码)
前言 本章节是用基本的Linux基本函数加上epoll调用编写一个完整的服务器和客户端例子,可在Linux上运行,客户端和服务端的功能如下: 客户端从标准输入读入一行,发送到服务端 服务端从网络读取一 ...
- Linux IO多路复用之epoll网络编程
前言 本章节是用基本的Linux基本函数加上epoll调用编写一个完整的服务器和客户端例子,可在Linux上运行,客户端和服务端的功能如下: 客户端从标准输入读入一行,发送到服务端 服务端从网络读取一 ...
- Linux IO多路复用 select/poll/epoll
Select -- synchronius I/O multiplexing select, FS_SET,FD_CLR,FD_ISSET,FD_ZERO #include <sys/time. ...
随机推荐
- 「 SPOJ GSS3 」 Can you answer these queries III
# 题目大意 GSS3 - Can you answer these queries III 需要你维护一种数据结构,支持两种操作: 单点修改 求一个区间的最大子段和 # 解题思路 一个区间的最大子段 ...
- vue 指令---气泡提示(手撸实战)
菜鸟学习之路//L6zt github 自己在造组件轮子,也就是瞎搞.自己写了个slider组件,想加个气泡提示.为了复用和省事特此写了个指令来解决.预览地址项目地址 github 我叫给它胡博 cs ...
- tiny4412u-boot烧写及根文件系统制作(不进入终端问题)
http://m.blog.csdn.net/article/details?id=51400196(转) VMware12 环境:ubuntu12.4 开发板:tiny4412 首先烧写bootlo ...
- jquery添加属性的方法
$("#id" ).prop('checked', true); $("#id" ).attr('checked', 'true');
- Nginx的启动过程
主要介绍Nginx的启动过程,可以在/core/nginx.c中找到Nginx的主函数main(),那么就从这里开始分析Nginx的启动过程. 涉及到的基本函数 源码: View Code Ngin ...
- maven+struts2环境搭建
首先在struts2.xml文件配置一个包,在包中配置一个action,新建action,新建视图,在action中定义由method定义的方法,这个方法一定要返回String类型,返回的是视图的名称 ...
- iRule Event Order - HTTPv12
- BGP表
BGP是一种基于策略的路由选择协议,让AS能够根据多种BGP属性来控制数据流的传输.运行BGP的路由器交换被称为路径矢量或者属性的NLRI.路径矢量信息中包含一个BGP-AS号列表称为AS-PATH属 ...
- 洛谷P4219 - [BJOI2014]大融合
Portal Description 初始有\(n(n\leq10^5)\)个孤立的点,进行\(Q(Q\leq10^5)\)次操作: 连接边\((u,v)\),保证\(u,v\)不连通. 询问有多少条 ...
- 【贪心】codeforces D. Minimum number of steps
http://codeforces.com/contest/805/problem/D [思路] 要使最后的字符串不出现ab字样,贪心的从后面开始更换ab为bba,并且字符串以"abbbb. ...