Linux IO 多路复用是什么意思?
写在前面:本文整理于知乎,原文链接为http://www.zhihu.com/question/32163005/answer/55772739,作者:罗志宇
再次向作者表示感谢~~
假设你是一个机场的空管, 你须要管理到你机场的全部的航线。 包含进港,出港, 有些航班须要放到停机坪等待,有些航班须要去登机口接乘客。
你会怎么做?
那么问题就来了:
非常快你就发现空管塔里面聚集起来一大票的空管员,交通略微繁忙一点,新的空管员就已经挤不进来了。
空管员之间须要协调,屋子里面就1, 2个人的时候还好,几十号人以后 。基本上就成菜市场了。
空管员常常须要更新一些公用的东西。比方起飞显示屏,比方下一个小时后的出港排期。最后你会非常惊奇的发现,每个人的时间最后都花在了抢这些资源上。
现实上我们的空管同一时候管几十架飞机稀松寻常的事情, 他们怎么做的呢?
他们用这个东西
![这里写图片描写叙述](https://pic2.zhimg.com/583d5ba3cee12e78befa8e2b749f4269_b.jpg)
这个东西叫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. ...
随机推荐
- MySQL本地登录及数据库导入导出
注意:本地MySQL服务要开启 更新整个数据库 1.将正式服务器上的数据库做备份 登录到正式服务器,执行如下命令:(注意空格) mysqldump -uroot –p密码 数据库名 -P 接口 --d ...
- 测试网站链接是否可用(wget和curl)
一.wget用法案例 系统给的命令参数如下: [root@litong_centos mysql3307]# wget --help GNU Wget 1.14, a non-interactive ...
- timeslot概念(还是不太懂呀!!)
rules: 1. event.triggered只会保持一个time_slot,在下一个time_slot将会丢失这个标记,如果不能保证在每一个time_slot都会检测到这个标志,那么将会丢失这个 ...
- Android开发——查询/杀死手机里正在运行的进程
0. 前言 以前有同学好像做过一个叫"自习君"的App,开启后自动检测用户这一天的自习时间,在学校里宣传广告还打了不少.其实实现原理非常简单,在SQlite数据库(也可以通过文件) ...
- (转)]PYTHON Tkinter GUI
import Tkinterroot=Tkinter.Tk()label=Tkinter.Label(root,text='hello ,python')label.pack() #将LAB ...
- 分享14个很酷的jQuery导航菜单插件
导航按钮是网站的非常重要的一部分,因其将网站的所有部分而集中一处,jQuery导航菜单插件在其中扮演重要的角色. 本文介绍了14个很酷的jQuery导航菜单插件,它们够漂亮.简单,并且完全兼容各种类型 ...
- 安装SecureCRT注册
注册方法 1.首先运行压缩包中的安装程序进行安装原版程序!2.安装完成后记得先不要运行程序!3.复制压缩包中的keygen.exe程序到安装目录!4.运行keygen.exe,点击Patch按钮对源程 ...
- Go切片基础
package main import "fmt" //切片(Slice)本身没有数据,是对底层Array的一个view //不使用指针就可以改数组内容 //slice可以向后扩展 ...
- [luoguP1186] 玛丽卡(spfa)
传送门 因为要随机删除一条边,而枚举所有边肯定会超时,经过发现,先求出一遍最短路,而要删除的边肯定在最短路径上,删除其他的边对最短路没有影响. 所以可以先求出最短路,再枚举删除最短路上的每一条边再求最 ...
- BZOJ:[JSOI2009]游戏Game【二分图匹配乱搞】
题目大意:n*m的棋盘,其中有些区域是禁区,两个人在棋盘上进行博弈,后手选择棋子的初始位置,然后先后手轮流将棋子往上下左右移动,走过的区域不能再走,问能否有一个位置使得后手必胜 Input 输入数据首 ...