Nginx是并发处理框架的代表者,很多后台业务都会放在Nginx容器中运行,以实现高吞吐,而Nginx能够支持高并发也是由于使用了异步非阻塞处理模型,本文将用通俗的话讲解异步、同步、阻塞、非阻塞的区别,以及IO多路复用。

一、同步和异步

同步与异步的重点是在消息通知的方式上,也就是调用后结果通知的方式不同。

同步与异步的区别

同步:当一个同步调用发出去后,调用者要一直等待调用结果的通知后,才能执行后续的操作。

异步:当一个异步调用发出去后,调用者不用一直死等调用结果的通知,可以立即返回,执行后续的操作。

那么,异步调用获取结果的方式有两种:一是通过主动轮训异步调用的结果。二是被调用方通过callback回调来通知调用者结果。

生活中的例子:

同步买奶茶:小明下单交钱,站在吧台等着拿奶茶。

异步买奶茶:小明下单交钱,老板给他一张小票,等奶茶做好了再来取。

那么,异步买奶茶时,小明怎么知道奶茶做好了:一是小明主动不断问老板:我的奶茶好了吗?二是老板吧奶茶做好了,大喊一声:奶茶好了,请小明取用,然后小明跑过去取回奶茶,这种方式叫做回调。

二、阻塞与非阻塞

阻塞与非阻塞的重点在于进/线程等待消息时候的行为,也就是等待消息的时候,当前进程or线程是挂起还是非挂起状态。

阻塞与非阻塞的区别

阻塞调用:调用发出去后,在消息返回前,当前进程or线程会被挂起,直到有消息返回时,才会被再次激活,期间不能处理其他的事务。

非阻塞调用:调用发出去后,不会阻塞当前的进程or线程,而会立即返回。

生活中的例子:

阻塞买奶茶:小明下单交钱,干等着拿奶茶,期间什么事情都不做。

非阻塞买奶茶,小明下单交钱,等待拿奶茶,等的过程中,时不时看微博刷新闻。

三、总结

通过以上可以总结:

1. 同步与异步,重点在于消息的通知方式。

2.阻塞与非阻塞,重点在于等消息时候的行为。

因此,共同组成4种方式:

1.同步阻塞:小明在吧台干等着拿奶茶

2.同步非阻塞:小明在吧台边刷微博边等着拿奶茶。

3.异步阻塞:小明拿着小票什么都不干,等着老板通知他拿奶茶。

4.异步非阻塞:小明拿着小票,刷着微博,等着老板通知他拿奶茶。

四、IO多路复用

IO多路复用英文名叫IO multiplexing,这个multiplexing是指单个线程记录跟踪每一个Sock的状态,尽可能提高服务器的吞吐能力。

最初的IO复用

所谓的IO复用是多个IO可以复用一个进程。

采用非阻塞模式,当一个连接过来时,我们不阻塞住,这样的一个进程可以同时处理多个连接。

比如一个进程接受了1000个连接请求,这个进程每次都从头到尾问一遍,“有IO事件没,有的话请给我来处理,没有的话我一会儿再来问下”。然后进程就不断重复询问这1000个连接的状态。这样会造成CPU的空转浪费,效率也很低。

升级版的IO复用

上面的古老IO复用逻辑效率很感人,于是引入了一个代理,这个agent可以同时观察多个IO流事件。

产生了两个代理:select和poll。

select和poll代理原理:

poll是基于select的优化产生的,原理上其实一样:

当连接有IO流事件产生时,就会主动唤醒进程处理。不过进程不清楚究竟是哪一个连接产生的IO流事件,于是挨个问,最终得出结果。

select是第一个实现版本(1983年在BSD里面实现)

1997年实现poll版本

select和poll原理是一样的,不过poll将select只能观察1024个连接优化成可观察无限个连接。

总之,select和poll实现还不够好,因为会产生CPU浪费的情况,如果有一个agent可以知道哪个连接有了IO流事件,就可以迅速定位到该连接,并且能够确定是读操作还是写操作岂不是更加美好了。因此,产生了epool 多路复用。

epoll IO多路复用

epoll代理原理

当连接有IO流事件产生时候,epool会告诉进程哪个连接产生了IO流事件,然后进程就会去处理该连接。

epoll是IO多路复用中很优秀的实现,修复了poll和select的缺陷:

1.epoll是线程安全的。select是线程不安全的,如果将一个sock加入select,然后另外一个线程发现此sock不可用,需要回收。select是不支持的,如果你强制关掉此sock会导致未知后果。poll优化了1024的链接限制,并且poll不用传入数组,接口设计更加优雅。

2.epoll不仅会告诉sock组里面有数组,还会告诉具体的sock组,不用去想法设法寻找了,提高CPU利用率。

缺点:

epoll只有Linux支持。

epoll与select/poll的最大区别

1.epoll内部使用了mmap共享了用户和内核的部分空间,避免数据来回拷贝。

2.epoll基于事件驱动,epoll_ctl注册事件并注册callback回调函数,epoll_wait返回发生的事件,解决了select/poll的大量轮训。

异步非阻塞和IO多路复用的应用

Nginx异步非阻塞模型

nginx优秀的地方是因为采用了异步非阻塞和IO多路复用机制

nginx进程由1个master进程和多个work进程组成,每当到了来一个request,会有worker进程去处理,但是不是全程处理,如果处理过程中有出现阻塞的地方,比如转发request并等待请求返回,它会首先注册一个事件:如果upstream返回后,请告诉我,我会接手继续之前的工作,这叫做异步。举个例子,使用uwsgi和nginx部署python web后台时候,nginx只会讲request转发给uwsgi,并且异步等待请求返回,如果这个时刻有新的request到来,此work进程会马上处理新的request,这就是非阻塞和IO多路复用。一旦上游服务器返回了,worker进程继续接手,这个回调过程叫做异步回调

参考资料

https://segmentfault.com/a/1190000007614502

https://www.zhihu.com/question/32163005

https://www.zhihu.com/question/22062795

异步、非阻塞和IO多路复用总结的更多相关文章

  1. 并发\并行,同步\异步,阻塞\非阻塞,IO多路复用解释

    并发.并行 并发:是指一个时间段内,有几个程序在同一个CPU上运行,但是任意时刻只有一个程序在CPU上运行.由于CPU的运行速度极快,可以在多个程序之间切换,这样造成一个假象就是多个程序同时在运行.并 ...

  2. 通俗讲解 异步,非阻塞和 IO 复用

    1. 阅前热身 为了更加形象的说明同步异步.阻塞非阻塞,我们以小明去买奶茶为例. 1.1 同步与异步 同步与异步的理解 同步与异步的重点在消息通知的方式上,也就是调用结果通知的方式. 同步: 当一个同 ...

  3. Python web框架 Tornado(二)异步非阻塞

    异步非阻塞 阻塞式:(适用于所有框架,Django,Flask,Tornado,Bottle) 一个请求到来未处理完成,后续一直等待 解决方案:多线程,多进程 异步非阻塞(存在IO请求): Torna ...

  4. Python web框架 Tornado异步非阻塞

    Python web框架 Tornado异步非阻塞   异步非阻塞 阻塞式:(适用于所有框架,Django,Flask,Tornado,Bottle) 一个请求到来未处理完成,后续一直等待 解决方案: ...

  5. 并发式IO的解决方案:多路非阻塞式IO、多路复用、异步IO

    在Linux应用编程中的并发式IO的三种解决方案是: (1) 多路非阻塞式IO (2) 多路复用 (3) 异步IO 以下代码将以操作鼠标和键盘为实例来演示. 1. 多路非阻塞式IO 多路非阻塞式IO访 ...

  6. 转一贴,今天实在写累了,也看累了--【Python异步非阻塞IO多路复用Select/Poll/Epoll使用】

    下面这篇,原理理解了, 再结合 这一周来的心得体会,整个框架就差不多了... http://www.haiyun.me/archives/1056.html 有许多封装好的异步非阻塞IO多路复用框架, ...

  7. Python异步非阻塞IO多路复用Select/Poll/Epoll使用,线程,进程,协程

    1.使用select模拟socketserver伪并发处理客户端请求,代码如下: import socket import select sk = socket.socket() sk.bind((' ...

  8. IO多路复用与异步非阻塞

    1.基于socket,发送http请求 import socket import requests # 方式一 list=['li','gh ','nn'] for i in list: ret=re ...

  9. 网络IO-阻塞、非阻塞、IO复用、异步

    网络socket输入操作分为两个阶段:等待网络数据到达和将到达内核的数据复制到应用进程缓冲区.对这两个阶段不同的处理方式将网络IO分为不同的模型:IO阻塞模型.非阻塞模型.多路复用和异步IO. 一 阻 ...

随机推荐

  1. RN 各种小问题

    问题:vs code 无法启动 双击无反应 方法:控制台 输入 netsh winsock reset 重启 vs 问题:RN Debugger Network 不显示 源网页:https://git ...

  2. Spring的IOC原理

    1. IoC理论的背景 我们都知道,在采用面向对象方法设计的软件系统中,它的底层实现都是由N个对象组成的,所有的对象通过彼此的合作,最终实现系统的业务逻辑. 图1:软件系统中耦合的对象 如果我们打开机 ...

  3. ASP.NET页面跳转的三大方法详解

    ASP.NET页面跳转有什么方法呢?,现在给大家介绍三种方法,他们的区别是什么呢?让我们开始吧: ASP.NET页面跳转1.response.redirect 这个跳转页面的方法跳转的速度不快,因为它 ...

  4. Python语法进阶

    1.变量进阶 2.局部变量.全局变量  3.函数进阶 4.函数进阶

  5. 20175236 2018-2019-2 《Java程序设计》第五周学习总结

    教材学习内容总结 接口回调 1.接口属于引用型变量,可以存放实现该接口类的实例的引用,即存放对象的引用. 2.接口回调理解上跟对象的上转型对象差不多. 理解接口 接口可以抽象出重要的行为标准. 接口多 ...

  6. 【算法习题】正整数数组中和为sum的任意个数的组合数

    1.递归实现(参考:https://blog.csdn.net/hit_lk/article/details/53967627) public class Test { @org.junit.Test ...

  7. 03-在tomcat部署网站多个网站

    在Tomcat服务器发布两个项目 CRM  OA server.xml配置文件 <Context docBase="C:\crm" path="/crm" ...

  8. 刘志梅201771010115.《面向对象程序设计(java)》第十五周学习总结

    实验十五  GUI编程练习与应用程序部署 实验时间 2018-12-6 1.实验目的与要求 (1)一个JAR文件既可以包含类文件,也可以包含诸如图像和声音这些其他类型的文件. 创建一个新的JAR文件应 ...

  9. hdfs知识点《转》

    HDFS知识点总结   学习完Hadoop权威指南有一段时间了,现在再回顾和总结一下HDFS的知识点. 1.HDFS的设计 HDFS是什么:HDFS即Hadoop分布式文件系统(Hadoop Dist ...

  10. redis过期机制(官网文档总结)

    官网地址:https://redis.io/commands/expire redis过期定义如下: Set a timeout on key. After the timeout has expir ...