🔥码云GVP开源项目 12k star Uniapp+ElementUI 功能强大 支持多语言、二开方便! 广告
## IO模型 ![](http://cdn.aipin100.cn/3e883e57e229a4b7fecb66e43b6c799b) [深入浅出Unix IO模型](https://mp.weixin.qq.com/s/I_KdtqBwq8IYfmtIJeUlyA) [Linux IO模式及 select、poll、epoll详解 - 人云思云 - SegmentFault 思否](https://segmentfault.com/a/1190000003063859) [Linux编程之select - Madcola - 博客园](https://www.cnblogs.com/skyfsm/p/7079458.html) > select系统调用的的用途是:在一段指定的时间内,监听用户感兴趣的文件描述符上可读、可写和异常等事件。 > > 从流程上来看,使用select函数进行IO请求和同步阻塞模型没有太大的区别,甚至还多了添加监视socket,以及调用select函数的额外操作,效率更差。但是,使用select以后最大的优势是用户可以在一个线程内同时处理多个socket的IO请求。**用户可以注册多个socket,然后不断地调用select读取被激活的socket,即可达到在同一个线程内同时处理多个IO请求的目的。而在同步阻塞模型中,必须通过多线程的方式才能达到这个目的。** > > **对socket进行扫描时是线性扫描,即采用轮询的方法,效率较低**:当套接字比较多的时候,每次select()都要通过遍历FD_SETSIZE个Socket来完成调度,不管哪个Socket是活跃的,都遍历一遍。这会浪费很多CPU时间。**如果能给套接字注册某个回调函数,当他们活跃时,自动完成相关操作,那就避免了轮询,这正是epoll与kqueue做的。** ***** ### 1. 阻塞式IO模型 **阻塞体现在:** 其系统调用直到数据包到达且被复制到应用进程的缓冲区或者发生错误时才返回,**在此期间会一直等待**(等待IO返回期间不能做任何事情) **同步体现在:** 在等待的过程中,系统不提供通知服务,需要调用方一直等着知道系统IO完成。 **优点:** 简单,容易理解,最符合我们对自上而下执行的代码的理解。 **缺点:** 效率低下,不能充分利用机器性能。 > 实现最高效率就是要榨干机器的每一寸性能而不是在等待网络IO时把CPU晾在一边闲着 ***** ### 2. 非阻塞式IO模型: **非阻塞体现在:** 在IO没有准备好数据时,recvfrom直接返回一个错误(`WSAEWOULDBLOCK` 错误),而不是被阻塞着而干不了其它事。 **同步体现在:** 在等待的过程中,系统不提供通知服务,需要调用方一直等着直到系统IO完成。 优点:与阻塞式IO相比,非阻塞IO效率有所提升。 缺点:需要不断地主动获取IO状态(类似数据库乐观锁的重试),效率不高 ***** ### 3. IO复用模型 **复用体现在:** 1. 复用了什么?…… **阻塞体现在:** 用户进程阻塞在select/poll上,而不是阻塞在具体的IO操作上,**不过由于是阻塞,所以还是做不了其它事。** **异步体现在:** 在等待select的过程中,系统提供通知服务,你只需要等待select的通知就好。 **优点:** 用户进程不用阻塞于具体的IO操作,而且多路复用器可以监听多个IO文件描述符。 **缺点:** 内部实现中,监听文件描述符是采用的轮询的方式,效率不高。 [C10K问题 - 简书](https://www.jianshu.com/p/ba7fa25d3590) ``` C10K问题的解决方案 从网络编程技术的角度来说,主要思路: 每个连接分配一个独立的线程/进程 同一个线程/进程同时处理多个连接 每个进程/线程处理一个连接 该思路最为直接,但是申请进程/线程是需要系统资源的,且系统需要管理这些进程/线程,所以会使资源占用过多,可扩展性差 ``` > 每个进程/线程同时处理 多个连接(I/O多路复用) > > 复用少数几个进程的处理多个客户端连接 [PHP socket初探 --- select系统调用](https://blog.ti-node.com/blog/6389426571769282560) ***** ### 4. 信号驱动式IO模型 **非阻塞体现在:** 用户进程只要调用sigaction(安装信号处理器,定义信号处理的action)后**就能立即返回**,不会被阻塞。当操作系统的文件描述符就绪时,会发送信号给用户进程,用户进程再调用recvfrom开始IO操作。 **异步体现在:** 当前进程不受阻塞,在等待信号通知的过程中,可以继续做其他事,**在操作系统的文件描述符就绪时,会发送信号给用户进程,用户进程再调用recvfrom开始IO操作。** **优点:** 相较于IO复用模型效率提升了。 **缺点:** 没有明显缺点。 ***** ### 5. 异步IO模型 **非阻塞体现在:** 只需要告诉(aio_read)操作系统当某个IO准备好后直接内核启动某个操作,**就直接返回。**(注意这里的返回不是指退出) **异步体现在:** 当前进程不受阻塞,在等待信号通知的过程中,可以继续做其他事,而在该IO操作完成时操作系统内核会以发送信号的方式通知我们(通过aio_read中定义的信号处理器接收通知)。 **优点:** 相较于信号驱动式IO模型可以说是更进一步了,直接将等待IO和完成IO后的操作一并交给内核了。 **缺点:** 暂无缺点。 ***** ### 总结 可以看到其实我们日常中写的最多的代码就是第一种,阻塞式IO模型,这也是最简单的一种IO模型,就像自上而下执行的代码那样简单直观,是最容易理解和符合人类直观的。 另外需要注意,无论是自己等待结果,或是自己轮询结果,还是等待结果通知,这些都是需要自己不退出才行。 ***** ### 名词释义 **阻塞/非阻塞:** 指事物/事件运行过程中相互依赖影响的关系,关注的是在等的过程中,还能不能干别的。 **同步/异步:** 指事物/事件运行过程中的依赖关系。 **串行/并行:** 指多个事物/事件运行顺序关系(一般是多个相关联的事物) **并发/非并发:** 指一个系统同时为多人提供服务或同时提供多种服务的能力或模式。 ***** ### 同步和异步的深入分析: 这个概念相对复杂一些,不那么容易理解,需要从多个方面去讨论,才能理解得更加立体。 #### 1. 从最终如何获得结果来看 **同步:** 靠自己一直等到结果。 **异步:** 不自己等,让系统告诉你的结果。 **关注的是:** 从哪里得到结果,或是如何得到结果。对于等的这件事,你是靠自己一直等到结果,还是不自己等,让系统告诉你的结果。重点的是你是如何得知结果的。 #### 2. 从与调用方对结果的依赖与否来看 **同步:** 调用方的继续执行依赖于被调用方的返回结果。(需要调用方立即返回结果) **异步:** 调用方的继续执行不依赖于被调用方的返回结果。(不需要调用方立即返回结果) **关注的是:** 调用方对被调用方返回结果的依赖性。 #### 同步在生活中的例子 >[tip] **不同场景下,“同步”这个词所表示的意思可能是不同的,比如生活中“同步”往往表示;两个事物的运行频率或相互作用的关系,如:数据与XX保持同步更新;与XX团队一起同步开展工作;走路时我们的步调保持同步一致;电机齿轮依靠同步带同步转动。** ![](http://cdn.aipin100.cn/18-1-7/90810005.jpg) 生活中也有很多同步/同时的例子(异步的概念则在生活中应用很少),比如电机内部齿轮上的那个皮带(套在两个齿轮上),叫做同步带,显然,一个齿轮转动时能通过同步带来带动另一个齿轮随之转动,此时两个齿轮是同时,同步转动的,**此处同步的意义是指两个齿轮的相互作用,且转动是同时发生的**。A转动,B也随之转动;A停止,B也会同时停止。(注意这里并不是指齿轮转动的角度,实际上两个齿轮大小不一样,转动角度是不同的) >[danger] **同步带 是现在我唯一能找到的,可以证明两个事件(转动)是同时发生(并行)的案列。** (你还知道哪些其它生动的例子,期待你的留言!) ***** ### 参考 [还不懂 select, epoll 吗?](https://mp.weixin.qq.com/s/71-X1urvqgFG08cxS4TNvA) [你分得清分布式、高并发与多线程吗?](https://mp.weixin.qq.com/s/8CutFewHv81jzhGBfOhd6w) [面试官问:一个 TCP 连接可以发多少个 HTTP 请求?我懵了!](https://mp.weixin.qq.com/s/93-WoFTGeiW-8iduFs59hA) [Spring Cloud 分布式服务限流实战,已经为你排好了](https://mp.weixin.qq.com/s/dqvRpqkQBObKRjvpM-QgxQ) [全球 IPv4 地址耗尽,IPv6 来了!](https://mp.weixin.qq.com/s/wMdDiu0o4JfUiqD8hAB75w) [彻底搞懂高性能I/O之道](https://mp.weixin.qq.com/s/gSLIIOo3KJ3ihXNEcSbpKQ) [她刚来,我就失宠了](https://mp.weixin.qq.com/s/EapnC7Bh8RVgp6c1q27PXA) [现代 IM 系统中消息推送和存储架构的实现](https://mp.weixin.qq.com/s/LBLaFMERpIB3UoYFEGV5WQ) [还不懂 select, epoll 吗?](https://mp.weixin.qq.com/s/71-X1urvqgFG08cxS4TNvA) [java并发编程系列:wait/notify机制](https://mp.weixin.qq.com/s/OriB-ouTDuCzquoFmjv9Lg)(wait和sellp的区别) [Linux惊群相关问题分析](https://mp.weixin.qq.com/s/ExRqSTBQ1_Z82SdgVUhOwg) [来点硬核的:什么是RDMA?](https://mp.weixin.qq.com/s/b6NaCu0_M-__XHWpKODx6w) [一个字节的网络漫游故事独白](https://mp.weixin.qq.com/s/EC5cgQ1ne9ZR0jFvznHBfg) [集线器、交换机与路由器的区别](https://mp.weixin.qq.com/s/8KU4nZYstuK_qZesljipTg) [微服务架构的理论基础 - 康威定律](https://mp.weixin.qq.com/s/J7A2l8GKEi4NVC_rpUxIRg) > 错误流淌在分布式系统的血液里。解决方法不是消灭这些问题,而是容忍这些问题,在问题发生时,能自动回复 [TCP 协议简介](https://mp.weixin.qq.com/s/Ah8GJRAkPviYYtbxzNaxBQ) [【系统编程】五种IO模型分析](https://mp.weixin.qq.com/s/9YXsJo_u2zVNqvABoGqfqg) > 所谓的IO模型,描述的是出现I/O等待时进程的状态以及处理数据的方式。 [【底层原理】网络数据传输时经历了哪些buffer](https://mp.weixin.qq.com/s/ZaQ6rpT_jOyaEtW7YPNXZw) > 对node层不太了解 没太看懂。。。我们的结构是html js css 全部署在cdn上,js访问后端的api > 这是最简单普通的一种方案,但是不够强大,还是用node + rpc的方式最好,是目前最好的方式。 [一个网卡的自述](https://mp.weixin.qq.com/s/JGsnWFhYPEwHwy7JsCNyNg) [非阻塞 I/O 和多路复用+select、poll、epoll模型详解](http://toutiao.com/group/6554223409138500110/?iid=31395168747&app=news_article_lite&timestamp=1526046953&wxshare_count=1&tt_from=weixin&utm_source=weixin&utm_medium=toutiao_android&utm_campaign=client_share) [张大胖的socket](https://mp.weixin.qq.com/s/XmWVy2ARauSBoehygs4Zvw) [网络编程 - NIO](https://mp.weixin.qq.com/s/fg36xDx--otVPACj391X0w) [新手入门贴:史上最全Web端即时通讯技术原理详解](http://www.52im.net/thread-338-1-1.html) [手写一个 WebSocket 协议](https://mp.weixin.qq.com/s/Tn81wt-_fWSbw_2gk2gmeg) [PHP Socket编程进阶指南](https://cloud.tencent.com/developer/news/271302) [Java 线程通信之 wait/notify 机制](https://mp.weixin.qq.com/s/x6jt8R0czfcsTolnZwVZmQ) [面试官:MAC 地址为什么不需要全球唯一?](https://mp.weixin.qq.com/s/ihjNnqgJty7YKC94sJ-0PA) [超强图文|并发编程【等待/通知机制】就是这个feel~](https://mp.weixin.qq.com/s/o6Yse51tPLv27GVq22ifyA) [使用虚幻引擎 4 年,再谈谈它的网络架构](https://mp.weixin.qq.com/s/qKg3iVHZYhqpmNXDfc1pjA) [Linux服务端最大并发数是多少?](https://mp.weixin.qq.com/s/YIVrgFUZADcSwCrV1q-yaA) [中断还是轮询?取个数据包真麻烦!](https://mp.weixin.qq.com/s/QmZP0P4BrSJ1p6YI6cmyVQ) [为什么像王者荣耀这样的游戏 Server 不愿意使用微服务?](https://mp.weixin.qq.com/s/PGFlbKwZQvAjX1e5bqNzxg) [如何用一行代码让 gevent 爬虫提速 100%](https://mp.weixin.qq.com/s/eZK5qevjACdNfq-PyqpG7Q) [Redis 6.0 除了多线程,这个功能也贼牛逼!](https://mp.weixin.qq.com/s/6e0gahpYWpIBSFpTBBpEgg) [完了!TCP出了大事!](https://mp.weixin.qq.com/s/iBk-kEj2tJqMCuFOdXCLEA) [图解Linux网络包接收过程](https://mp.weixin.qq.com/s/GoYDsfy9m0wRoXi_NCfCmg) [CPU:网卡老哥,你到底怎么工作的?](https://mp.weixin.qq.com/s/9E_pl_V2brzgmX3PfedwlQ) [框架篇:linux网络I/O+Reactor模型](https://mp.weixin.qq.com/s/Nv7h7a_mhOsG1kLYz6OueA) [程序员应如何理解高并发中的协程](https://mp.weixin.qq.com/s/dSY1c1rKh6h5XT3ds0EyKg) [点个外卖,我把「软中断」搞懂了](https://mp.weixin.qq.com/s?__biz=MzUxODAzNDg4NQ==&mid=2247487248&idx=1&sn=9a1bde19deb1cf734db164d705b7c468&chksm=f98e4bbacef9c2ac7a9e299038fa06f69e0a87ad3d88fdb6874c3c482d3a39a36bd1b6e2bde4&scene=132#wechat_redirect) [今天我“蹂躏”了一个包](https://mp.weixin.qq.com/s/PzzGZb9Y4lSHIjmW4ai9HA) [本文把TCP/IP讲绝了!](https://mp.weixin.qq.com/s/4_WbTXwiJPNxBa8Rq28ROg) ~~~ 我想认识你下,这是我的电话(期待回信) 好的,收到你的电话了,这是我的电话(期待回信) 嗯啦,我也收到你的电话了,我们开始交往吧 ... 我觉得我们该结束了(期待回复) 你确认你已经不爱我了吗,想好再说(期待回复) 确认,想好了,我们分开吧(期待回复) 好,尊重你的意愿,好聚好散,保重 (错,并不是这样的) 我对你已经没有感情了 (女) 我知道了 (男) 我对你也没有感情了(男) 我知道了 (女)(男收到后就关闭) (女等待 2msl 没回应后才关闭)(先说放手的人才是不愿放手的人,她还抱有期待,如果这 2msl 内他有回音,说后悔了,哪怕是简单的一句问候,她愿意放下卑微的尊严,奋不顾身的再爱他一次,在感情面前讲什么自我,要再次扑到怀里大哭一场,要痛痛快快的诉说所有的委屈和不甘,...,可是没有如果,爱得最深的人总是最敏感,最容易受伤,明明知道自己想要什么,可总是让自己歇斯底里遍体鳞伤。问世间情为何物,愿得一人心白首不分离) ~~~ ~~~ 三次握手: A:你好,想认识你,这是我的微信 B:好啊,这是我的微信,我看到你的微信了 (A 求认识成功) A:嗯,我也看到你的微信了 (B交友成功) 四次挥手: A:我不爱你了 B:我知道了 B:我也不爱你了 A:好,后会无期 A发出后等待2MSL(最长报文段寿命,确保消息发出去)后断开连接,B收到后就立即断开连接 说放手的那个人才是最舍不得的那个人 link: https://www.cnblogs.com/skynet/archive/2010/12/12/1903949.html https://blog.csdn.net/qq\_38950316/article/details/81087809 ~~~ [从一个程序员的角度告诉你:“12306”有多牛逼?](https://mp.weixin.qq.com/s/O9I_HcF_rAWur1sCi_eKfA) > 自 Epoll 网络架构模型解决了 c10k 问题以来,异步越来越被服务端开发人员所接受,能够用异步来做的工作,就用异步来做,在功能拆解上能达到意想不到的效果。 ? 这点在 Nginx、Node.JS、Redis 上都能体现,他们处理网络请求使用的 Epoll 模型,用实践告诉了我们单线程依然可以发挥强大的威力。 [程序员怎么会不知道 C10K 问题呢?](https://mp.weixin.qq.com/s/MX4Kt8wiuhTEN1UxtWEqMQ) [从HTTP到HTTP/3的发展简史](https://mp.weixin.qq.com/s/ROiUE9qUEo7rYdOME0c2Rg) > UDP 是一种无状态协议(持久连接只是其之上的抽象) > > UDP 是一种无状态协议(持久连接只是其之上的抽象),**使 QUIC 能够支持一些很大程度上忽略了数据包传递复杂性的功能。例如,从理论上讲,客户端更改其 IP 地址中间连接(例如智能手机从移动网络跳转到家庭 wifi)时不应中断连接,因为该协议允许在不同 IP 地址之间迁移而无需重新连接。** > > 这和TCP四元组连接有什么不同吗?连接的本质是什么? [QUIC 0-RTT实现简析及一种分布式的0-RTT实现方案](https://cloud.tencent.com/developer/article/1594468) [漫画:一台 Linux 服务器最多能支撑多少个 TCP 连接](https://mp.weixin.qq.com/s/gsoESy5viCgX0wXqUi4QPw) [图解 QUIC](https://cangsdarm.github.io/illustrate/quic) [revoltphp/event-loop: Revolt is a rock-solid event loop for concurrent PHP applications. --- revoltphp/event-loop:Revolt 是用于并发 PHP 应用程序的坚如磐石的事件循环。](https://github.com/revoltphp/event-loop) ***** last update:2018-10-21 15:33:41