处理大并发之一 对异步非阻塞的理解

原创 2013年05月16日 20:22:27

处理大并发之一 对异步非阻塞的理解

    在研究nginxnode.js的时候常会遇到异步、非阻塞等,之前自己也经常使用epoll,对其同步与阻塞,异步与非阻塞有了一定的认识,现对参考资料总结下。

    首先讨论下使用事件驱动,异步编程的优点:

    充分利用了系统资源,执行代码无须阻塞等待某种操作完成,有限的资源可以用于其他的任务。其非常适合于后端的网络服务编程。

    在服务器开发中,并发的请求处理是个大问题,阻塞式的函数会导致资源浪费和时间延迟。通过事件注册、异步函数,开发人员可以提高资源的利用率,性能也会改善。其nginxnode.js处理并发都是采用的事件驱动异步非阻塞模式。其中nginx中处理并发用的是epollpoll,queue等方式,node.js使用的是libev,它们对大规模的HTTP请求处理的都很好。

阻塞

    《node.js开发指南》是这样定义的:线程在执行中如果遇到(I/O 操作)如磁盘读写或网络通信,通常要耗费较长的时间,这时操作系统会剥夺这个线程的 CPU 控制权,使其暂停执行,同时将资源让给其他的工作线程,这种线程调度方式称为 阻塞。当 I/O 操作完毕时,操作系统将这个线程的阻塞状态解除,恢复其对CPU的控制权,令其继续执行。这种 I/O 模式就是通常的同步式 I/O(Synchronous I/O)或阻塞式 I/O(Blocking I/O)。

非阻塞

    非阻塞是这样定义的,当线程遇到 I/O 操作时,不会以阻塞的方式等待 I/O 操作的完成或数据的返回,而只是将 I/O 请求发送给操作系统,继续执行下一条语句。当操作系统完成 I/O 操作时,以事件的形式通知执行 I/O 操作的线程,线程会在特定时候处理这个事件。

对比阻塞与非阻塞

    阻塞模式下,一个线程只能处理一项任务,要想提高吞吐量必须通过多线程。

    非阻塞模式下,一个线程永远在执行计算操作,这个线程所使用的 CPU 核心利用率永远是 100%,I/O 以事件的方式通知。

    在阻塞模式下,多线程往往能提高系统吞吐量,因为一个线程阻塞时还有其他线程在工作,多线程可以让 CPU 资源不被阻塞中的线程浪费。

    而在非阻塞模式下,线程不会被 I/O 阻塞,永远在利用 CPU。多线程带来的好处仅仅是在多核 CPU 的情况下利用更多的核。

    来看看《深入浅出Node.js对异步I/O的解释,在操作系统中,程序运行的空间分为内核空间和用户空间。我们常常提起的异步I/O,其实质是用户空间中的程序不用依赖内核空间中的I/O操作实际完成,即可进行后续任务。

    I/O的阻塞与非阻塞的解释

    阻塞模式的I/O会造成应用程序等待,直到I/O完成。同时操作系统也支持将I/O操作设置为非阻塞模式,这时应用程序的调用将可能在没有拿到真正数据时就立即返回了,为此应用程序需要多次调用才能确认I/O操作完全完成。

    I/O的同步与异步I/O的同步与异步出现在应用程序中。如果做阻塞I/O调用,应用程序等待调用的完成的过程就是一种同步状况。相反,I/O为非阻塞模式时,应用程序则是异步的。

    参照《node.js入门经典》中对同步的解释,同步的代码意味着每一次执行一个操作,在一个操作完成之前,代码的执行会被阻塞,无法移到下一个操作上。也就是说代码的执行会在函数返回前停止。直到函数返回后,代码才会继续执行。

相反,异步就意味着函数的执行无需等待某个操作的结果就可以继续执行,其操作的结果会在事件发生时由回调来处理。

异步I/O优缺点

    使用同步IO,它的优点是可以使程序调试方便,但是它的缺点也是明显的,程序的执行过程中如果入到一些耗时的IO操作,程序的执行都要等待该IO的完成,在这个等待的过程中,程序无法充分利用CPU,导致了CPU的闲置,为了充分利用CPU,和IO并行操作,常用的方法有2中:

    (1)多线程单进程

    多线程的设计之处就是为了在共享的程序空间中,实现并行处理任务,从而达到充分利用CPU的效果。

    多线程缺点:

    其一、执行时(线程切换)上下文交换的开销较大,一个线程大约需要2M的内存空间,占用资源较大。

    其二、状态同步(锁)的问题,它也使得程序的编写和调用复杂化。

    (2)单线程多进程

    为了避免多线程造成的使用不便问题,有的语言选择了单线程保持调用简单化,采用启动多进程的方式来达到充分利用CPU和提升总体的并行处理能力。它的缺点在于业务逻辑复杂时(涉及多个I/O调用),因为业务逻辑不能分布到多个进程之间,事务处理时长要远远大于多线程模式。

异步I/O与轮询技术

    当进行非阻塞I/O调用时,要读到完整的数据,应用程序需要进行多次轮询,才能确保读取数据完成,以进行下一步的操作。轮询技术的缺点在于应用程序要主动调用,会造成占用较多CPU时间片,性能较为低下。现存的轮询技术有以下这些: read、select、poll、epoll、pselect、kqueue 

    read是性能最低的一种,它通过重复调用来检查I/O的状态来完成完整数据读取。

    select是一种改进方案,通过对文件描述符上的事件状态来进行判断。

    操作系统还提供了poll、epoll等多路复用技术来提高性能。

    轮询技术满足了异步I/O确保获取完整数据的保证。但是对于应用程序而言,它仍然只能算时一种同步,因为应用程序仍然需要主动去判断I/O的状态,依旧花费了很多CPU时间来等待。上一种方法重复调用read进行轮询直到最终成功,用户程序会占用较多CPU,性能较为低下。而实际上操作系统提供了select方法来代替这种重复read轮询进行状态判断。select内部通过检查文件描述符上的事件状态来进行判断数据是否完全读取。但是对于应用程序而言它仍然只能算是一种同步,因为应用程序仍然需要主动去判断I/O的状态,依旧花费了很多CPU时间等待,select也是一种轮询。

理想的异步I/O模型

    理想的异步I/O应该是应用程序发起异步调用,而不需要进行轮询,进而处理下一个任务,只需在I/O完成后通过信号或是回调将数据传递给应用程序即可。

    暂时就整理这么多吧,感觉好多看过的东西都忘记了,回头会写一篇关于epoll使用的详细例子,该例子支持2W并发是通过的。哎,今天状态不好,写的不好,本打算自己多加点什么的,结果都是参考别人的,如有错误请大家指正,谢谢。

参考资料:

node.js入门经典》 George Ornbo 著 傅强 陈宗赋 译 人民邮电出版社

《深入浅出node.js

node.js开发指南》 BYVoid 人民邮电出版社

 

如是转载,请指明原出处:http://blog.csdn.net/feitianxuxue,谢谢合作!

深入理解非阻塞同步IO和非阻塞异步IO

这篇文章分析了Linux下的5种IO模型 http://blog.csdn.net/hguisu/article/details/7453390 很多人对阻塞 / 非阻塞, 同步 / 异步 的概...
  • ITer_ZC
  • ITer_ZC
  • 2014年09月15日 13:45
  • 14799

nginx学习(二)——基础概念之异步非阻塞

本章参考自淘宝的nginx主页nginx平台初探 上面讲了很多关于nginx的进程模型,接下来,我们来看看nginx是如何处理事件的。 有人可能要问了,nginx采用多worker的方式来...
  • xxcupid
  • xxcupid
  • 2016年09月10日 15:04
  • 3428

异步非阻塞开发模式的优越性

同步阻塞开发模式: 1. 服务端启动监听; 2. 接收到一个客户端连接时,申请一个线程处理(可以是线程池,也能是直接启动线程。) 3.然后是接收请求(接受请求时,线程阻塞在这里),处理请求,如果需要...
  • u013150151
  • u013150151
  • 2013年12月15日 15:42
  • 2599

处理大并发之一 对异步非阻塞的理解

处理大并发之一 对异步非阻塞的理解     在研究nginx和node.js的时候常会遇到异步、非阻塞等,之前自己也经常使用epoll,对其同步与阻塞,异步与非阻塞有了一定的认识,现对参考资料总...
  • qq_16836151
  • qq_16836151
  • 2016年03月08日 00:48
  • 795

高并发异步非阻塞程序消息发送处理机制

在网络IO密集型的高并发异步非阻塞程序里,网络的IO吞吐量一般远远跟不上CPU的处理能力, 程序在发送大量数据时,会导致TCP的发送缓冲区满,应用层在调用send或write等函数时会返回 EAGAI...
  • maypeter2008
  • maypeter2008
  • 2016年07月23日 18:31
  • 762

socket阻塞与非阻塞,同步与异步、I/O模型

socket阻塞与非阻塞,同步与异步 作者:huangguisu 1. 概念理解      在进行网络编程时,我们常常见到同步(Sync)/异步(Async),阻塞(Block)/非...
  • hguisu
  • hguisu
  • 2012年04月12日 16:35
  • 196044

异步与非阻塞之间的区别(看到的最清晰的说明)

Asynchronous I/O, or non-blocking I/O, is a form of input/output processing that permits other proce...
  • liaoqianwen123
  • liaoqianwen123
  • 2016年01月21日 16:56
  • 2009

彻底理解:阻塞、非阻塞、同步、异步、Reactor、Proactor

我以前是写AS3的,事件和回调无处不在,天生就是异步的,很少需要讨论这些概念。现在写C#,这些概念提的就多了,所以需要彻底搞明白。如果把技术的逻辑抽象出来,跟生活中的逻辑做比较,你会发现技术包含的道理...
  • llj1985
  • llj1985
  • 2016年06月01日 20:06
  • 1356

【高并发编程】再谈同步、异步、阻塞、非阻塞

同步、异步、阻塞、非阻塞的概念一直是计算机学科中很重要的概念,而这种细微的差别常常被大家混淆,我自己在过一段时间后也需要复习。今天再次翻出这个概念,仍然觉得不够清晰,今天再次深入了解了这四大天王。 以...
  • xxxxxx91116
  • xxxxxx91116
  • 2016年04月24日 16:13
  • 6552

IO - 同步,异步,阻塞,非阻塞 (亡羊补牢篇)

当你发现自己最受欢迎的一篇blog其实大错特错时,这绝对不是一件让人愉悦的事。 《 IO - 同步,异步,阻塞,非阻塞 》是我在开始学习epoll和libevent的时候写的,主要的思路来自于文中...
  • historyasamirror
  • historyasamirror
  • 2010年07月31日 12:51
  • 137318
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:处理大并发之一 对异步非阻塞的理解
举报原因:
原因补充:

(最多只允许输入30个字)