范文健康探索娱乐情感热点
投稿投诉
热点动态
科技财经
情感日志
励志美文
娱乐时尚
游戏搞笑
探索旅游
历史星座
健康养生
美丽育儿
范文作文
教案论文
国学影视

IO多路复用,从来没遇到过这么明白的文章

  大家好,我是涛哥。
  很多对技术有追求的读者朋友,做到一定阶段后都希望技术有所精进。有些读者朋友可能会研究一些中间件的技术架构和实现原理。比如,Nginx为什么能同时支撑数万乃至数十万的连接?为什么单工作线程的Redis性能比多线程的Memcached还要强?Dubbo的底层实现是怎样的,为什么他的通信效率非常高?
  实际上,上面的一些问题都和网络模型相关。本文从基础的概念和网络编程开始,循序渐进讲解Linux五大网络模型,包括耳熟能详的多路复用IO模型。相信读完本文,大家会对网络编程和网络模型有一个较清晰的理解。
  本文2800字,阅读需要10分钟。百度一百篇,不如收藏这一篇。
  基本概念
  我们先来了解几个基本概念。
  什么是I/O?
  所谓的I/O(Input/Output)操作实际上就是输入输出的数据传输行为。程序员最关注的主要是磁盘IO和网络IO,因为这两个IO操作和应用程序的关系最直接最紧密。
  磁盘IO:磁盘的输入输出,比如磁盘和内存之间的数据传输。
  网络IO:不同系统间跨网络的数据传输,比如两个系统间的远程接口调用。
  下面这张图展示了应用程序中发生IO的具体场景:
  通过上图,我们可以了解到IO操作发生的具体场景。一个请求过程可能会发生很多次的IO操作:
  1,页面请求到服务器会发生网络IO
  2,服务之间远程调用会发生网络IO
  3,应用程序访问数据库会发生网络IO
  4,数据库查询或者写入数据会发生磁盘IO
  阻塞与非阻塞
  所谓阻塞,就是发出一个请求不能立刻返回响应,要等所有的逻辑全处理完才能返回响应。
  非阻塞反之,发出一个请求立刻返回应答,不用等处理完所有逻辑。
  内核空间与用户空间
  在Linux中,应用程序稳定性远远比不上操作系统程序,为了保证操作系统的稳定性,Linux区分了内核空间和用户空间。可以这样理解,内核空间运行操作系统程序和驱动程序,用户空间运行应用程序。Linux以这种方式隔离了操作系统程序和应用程序,避免了应用程序影响到操作系统自身的稳定性。这也是Linux系统超级稳定的主要原因。
  所有的系统资源操作都在内核空间进行,比如读写磁盘文件,内存分配和回收,网络接口调用等。所以在一次网络IO读取过程中,数据并不是直接从网卡读取到用户空间中的应用程序缓冲区,而是先从网卡拷贝到内核空间缓冲区,然后再从内核拷贝到用户空间中的应用程序缓冲区。对于网络IO写入过程,过程则相反,先将数据从用户空间中的应用程序缓冲区拷贝到内核缓冲区,再从内核缓冲区把数据通过网卡发送出去。
  Socket(套接字)
  Socket可以理解成,在两个应用程序进行网络通信时,一个应用程序将数据写入Socket,然后通过网卡把数据发送到另外一个应用程序的Socket中。
  所有的网络协议都是基于Socket进行通信的,不管是TCP还是UDP协议,应用层的HTTP协议也不例外。这些协议都需要基于Socket实现网络通信。5种网络IO模型也都要基于Socket实现网络通信。实际上,HTTP协议是建立在TCP协议之上的应用层协议。HTTP协议负责如何包装数据,而TCP协议负责如何传输数据。
  绝大部分编程语言,都支持Socket编程,例如Java,Php,Python等等。而这些语言的Socket SDK都是基于操作系统提供的 socket 函数来实现的。不管是Linux还是windows,都提供了相应的 socket 函数。
  Socket 编程过程
  我们来看看Socket 编程过程是怎样的。
  不管Java、Python还是Php,很多编程语言都支持Socket编程。Linux,Windows等操作系统都开放了网络编程接口。只不过,各种编程语言对底层操作系统提供的网络编程接口做了封装而已。
  从服务端开始,服务端首先调用 socket函数,按指定的网络协议和传输协议创建 Socket ,例如创建一个网络协议为 IPv4,传输协议为 TCP 的Socket。接着调用bind函数,给这个 Socket 绑定一个 IP 地址和端口,绑定这两个的目的是什么?
  绑定端口的目的:当内核收到 TCP 报文,通过 TCP 头里的端口号,来找到我们的应用程序,然后把数据传递给我们
  绑定 IP 地址的目的:一台机器可能有多个网卡,每个网卡都对应一个 IP 地址,只有绑定一个网卡对应的IP时,内核在收到该网卡上的包,才会发给我们的应用程序
  绑定完 IP 地址和端口后,就可以调用 listen函数进行监听。如果我们要判定服务器上某个网络程序有没有启动,可以通过netstat命令查看对应的端口号是否被监听。
  服务端进入了监听状态后,通过调用 accept函数,来从内核获取客户端的连接,如果没有客户端连接,则会阻塞等待客户端连接的到来。
  那客户端是怎么发起连接的呢?客户端在创建好 Socket 后,调用 connect函数发起连接,该函数的参数要指明服务端的 IP 地址和端口号,然后众所周知的 TCP 三次握手就开始了。
  连接建立后,客户端和服务端就开始相互传输数据了,双方可以通过 read和write函数来读写数据。
  基于TCP 协议的 Socket 编程过程就结束了,整个过程如下图所示:
  网络IO模型
  5种Linux网络IO模型包括:同步阻塞IO、同步非阻塞IO、多路复用IO、信号驱动IO和异步IO。
  同步阻塞IO
  我们先看一下传统阻塞IO。在Linux中,默认情况下所有socket都是阻塞模式的。当用户线程调用系统函数read,内核开始准备数据(从网络接收数据),内核准备数据完成后,数据从内核拷贝到用户空间的应用程序缓冲区,数据拷贝完成后,请求才返回。从发起read请求到最终完成内核到应用程序的拷贝,整个过程都是阻塞的。为了提高性能,可以为每个连接都分配一个线程。因此,在大量连接的场景下就需要大量的线程,会造成巨大的性能损耗,这也是传统阻塞IO的最大缺陷。
  同步非阻塞IO
  用户线程在发起Read请求后立即返回,不用等待内核准备数据的过程。如果Read请求没读取到数据,用户线程会不断轮询发起Read请求,直到数据到达(内核准备好数据)后才停止轮询。非阻塞IO模型虽然避免了由于线程阻塞问题带来的大量线程消耗,但是频繁的重复轮询大大增加了请求次数,对CPU消耗也比较明显。这种模型在实际应用中很少使用。
  多路复用IO模型
  多路复用IO模型,建立在多路事件分离函数select,poll,epoll之上。在发起read请求前,先更新select的socket监控列表,然后等待select函数返回(此过程是阻塞的,所以说多路复用IO并非完全非阻塞)。当某个socket有数据到达时,select函数返回。此时用户线程才正式发起read请求,读取并处理数据。这种模式用一个专门的监视线程去检查多个socket,如果某个socket有数据到达就交给工作线程处理。由于等待Socket数据到达过程非常耗时,所以这种方式解决了阻塞IO模型一个Socket连接就需要一个线程的问题,也不存在非阻塞IO模型忙轮询带来的CPU性能损耗的问题。多路复用IO模型的实际应用场景很多,比如大家耳熟能详的Java NIO,Redis,Nginx以及Dubbo采用的通信框架Netty都采用了这种模型。
  下图是基于select函数Socket编程的详细流程。
  用一句话解释多路复用模型。多路:可以理解成多个网络连接(TCP连接)。复用:服务端反复使用同一个线程去监听所有网络连接中是否有IO事件(如果有IO事件就交给工作线程从对应的连接中读取并处理数据)。
  信号驱动IO模型
  信号驱动IO模型,应用进程使用sigaction函数,内核会立即返回,也就是说内核准备数据的阶段应用进程是非阻塞的。内核准备好数据后向应用进程发送SIGIO信号,接到信号后数据被复制到应用程序进程。
  采用这种方式,CPU的利用率很高。不过这种模式下,在大量IO操作的情况下可能造成信号队列溢出导致信号丢失,造成灾难性后果。
  异步IO模型
  异步IO模型的基本机制是,应用进程告诉内核启动某个操作,内核操作完成后再通知应用进程。在多路复用IO模型中,socket状态事件到达,得到通知后,应用进程才开始自行读取并处理数据。在异步IO模型中,应用进程得到通知时,内核已经读取完数据并把数据放到了应用进程的缓冲区中,此时应用进程
  直接使用数据即可。
  很明显,异步IO模型性能很高。不过到目前为止,异步IO和信号驱动IO模型应用并不多见,传统阻塞IO和多路复用IO模型还是目前应用的主流。Linux2.6版本后才引入异步IO模型,目前很多系统对异步IO模型支持尚不成熟。很多应用场景采用多路复用IO替代异步IO模型。
  本文完,请大家继续关注涛哥后续的技术原创!
  作者简介:曾任职于阿里巴巴,每日优鲜等互联网公司,任技术总监,15年电商互联网经历。

和胡歌的老师待了3天后,我找到了这辈子最爱的人如果给你3天时间,你会做什么?陪孩子度过久违的亲子时光,来一场说走就走的周边游,回一趟老家看看父母,又或者,宅在家连看5部美剧?上海戏剧学院青年话剧团里,有一群人选择用生命中的3天不焦虑的活着我相信,每个从焦虑坑里爬出来的人,一定会加倍的热爱生活,加倍的珍惜重生的快乐。我以前是比较孤傲的性格。女儿班上的家长,形形色色,各种群,一些话比较投机的家长还组了小群,她们闲时各种古今论英雄生当作人杰,死亦为鬼雄。至今思项羽,不肯过江东。这是古人对英雄的诠释。那么,对于生在和平年代的我们来说,英雄又是怎样的呢英雄一一是保家卫国,南征北战的豪迈。元末明初,我国沿海地区常安全感克服分离焦虑今天是萌萌第一天上幼儿园。一路上萌萌都看起来很不情愿,走一步停一步的,终于还是被妈妈拖到了教室。临走时候,妈妈叮嘱小女儿萌萌,在学校要好好听老师话,知道么?放学了妈妈就来接你,乖啊帮孩子建立安全感的重要两步,你做到了吗?安全感在孩子的成长中一直扮演着十分重要的角色。爸妈要让孩子知道,这个世界是安全的,他们是有人可以依靠的,爸妈永远是他们获得安全感的来源,这样,他们就会有足够的内心力量去探索这个世界老公爱冷战,我该怎么办?高情商伴侣绝不会做的4件事说到男人喜欢冷战,很多女人都感到自己深受其害吵架后他不理我的样子好欠揍,拿我跟空气一样。有时候我俩闹不愉快了,他就一直默不作声,于是我也不跟他说话,表面看着云淡风轻,但我内心特别火重阳节看望长辈,送这些就是送健康金秋九月,天高气爽,你可否记得重阳节这个日子呢?重阳节给老人送礼送什么好,该如何挑选给老人的重阳节礼物呢?九月初九重阳节,又被称为老人节,在这个特别的日子里,即使不能够陪伴在亲人身重阳丨岁岁重阳,今又重阳还记得儿时我们依偎在父母身旁细数满天星光欢声笑语满堂如今,我们带着父母的叮咛远行蓦然回首却发现白发已经漫上了他们的双鬓时光无情在我们未曾注意的地方他们正在慢慢变老九九重阳节重阳节,如何帮助孩子改掉丢三落四的坏毛病?孩子丢三落四是常见现象,孩子做事拖拖拉拉大手大脚,家长一边埋怨着,一方面跟在孩子后面查缺补漏,恨不得天天跟在孩子后面,唯恐孩子因为忘了东西而耽误事。很多家长都有去学校给孩子送忘记带想学天道佩恩的一袋米嘛?我教你啊注小编自己录得音频!情感表达得不到位还请大家多多包涵!(因为版权原因,就不适用原音频了)空耳音译一袋米要抗几楼一袋米要抗二楼一袋米要我给多嘞一袋米要我洗嘞口口有泥谁给你的一袋米呦森日产前CEO卡洛斯戈恩的日本大逃亡卡洛斯戈恩,CarlosGhosn,是曾经的日产救世主,曾经身兼法国雷诺董事长兼首席执行官,日产汽车会长社长兼首席执行官,三菱汽车董事长,以及雷诺日产三菱联盟首席执行官,是雷诺日产
春季长高黄金期,这7道好汤换着做,味美营养,孩子爱喝长个快春季是万物生长的好季节,对于正在生长发育中的孩子来说也不例外。一年之计在于春,春季孩子的生长速度是最快的,被称为长高黄金期。抓住这个黄金期进补,可以起到事半功倍的效果。今天给大家推江西婆婆做的早餐,走红朋友圈,网友天天这样吃,难怪彩礼高江西婆婆做的早餐,走红朋友圈,有的网友说能吃到婆婆做的早餐,真幸福有的网友说让婆婆做早餐给你吃,好意思吗还有的网友说天天这样吃,难怪彩礼高。之前晒年夜饭的时候,也有网友一直在说彩礼产后减肥的黄金期如何把握好减肥时机对于很多新妈来说产后最重要的事情除了照顾孩子就是恢复身材了,要知道大部分人都是上班族,而大妈的身材真的是不好意思见人,不过产后恢复要抓住时机,这样才能事半功倍。接下来为大家介绍一下江西婆婆做的早餐,在朋友圈火了,网友好吃实在,不需要假精致很多朋友问我,如果有下辈子,你还会远嫁吗?下辈子我绝不会远嫁了,因为远嫁对不起父母,但这辈子选择远嫁,我也不后悔。父母从不埋怨我远嫁,也从不问我什么时候回家。父母最大的期盼就是我过过年家人都爱吃它,一吃完就做,开胃解油腻,比肉更受欢迎每逢佳节胖三斤,仔细一瞧三公斤!过年这段时间,大家胖了没?往年春节我都会胖好几斤,今年回家不敢多吃。婆婆说,我留了这么多土鸡土鸭给你们吃,你不吃我会不开心的,你只管放心吃,我不会让开春后,多做这个吃,不煎不炸,蒸一蒸裹上一物就能吃,香甜软糯开春后,天气不冷不热,孩子也还没开学,可以多带孩子去郊外,感受一下春天的气息。我们家孩子很喜欢郊游,带上帐篷点心和水,可以玩上一整天。每次郊游,我们都喜欢带上一些自制的小点心,这些二月二龙抬头,记得要吃这菜,简单又美味,寓意一年开个好头农历二月初二,传说是龙抬头的日子,俗称青龙节龙头节,是我国的传统节日。每年二月二这天,理发店都格外热闹,正月不剃头,大家都等二月二这天剃头,其名曰剃龙头。除了剃龙头的习俗外,民间还这菜此时最鲜美,想吃需趁早,清内热防贫血,包饺子吃,老少皆宜阳春三月,万物复苏,到处一片生机勃勃的景象。这时,农村最不缺的就是野菜,田里山间小路两旁,到处都是郁郁葱葱的野菜。天气好的时候,挖野菜的人特别多,走到哪里都能看到提着篮子,拿着镰刀晒晒江西人的晚餐,4道菜成本不到40元,网友太值了,好想吃我们很快就要搬家了,在这里生活了几年,东西真不少,想想都很头疼。所以最近能不买的东西就不买了,包括菜也是。婆婆给我们的腊味和干菜还有很多,为了节约开支,也为了消耗掉这些存货,今天蒸早餐迷上吃它,不揉面不擀面,3分钟出锅,比包子油条好吃多了小区门口新开了一家网红酱香饼,生意非常火爆,但凡跟网红沾边的,价格都不便宜,凑热闹买了一次,一小袋就要6块钱,几下就吃没了。看到孩子爱吃,我决定在家试做一下。没想到第一次就做成功了招待婆婆我做了一桌菜,花了30元,网友就这伙食,真抠门婆婆之前在我们这边住了一段时间,还有很多东西在这里,我们这几天就要搬家了,我让婆婆过来收拾好,我们到时候一起搬过去。搬家最头疼的就是冰箱洗衣机那些电器了,最近一直都在清理冰箱里的食