文档章节

同步、异步、多线程与事件型综述

invictus_lee
 invictus_lee
发布于 2014/06/24 11:40
字数 1065
阅读 28
收藏 1

首先要了解什么是阻塞和阻塞式IO。
线程在执行中如果遇到磁盘读写或网络通信(统称IO操作),通常要耗费较长的时间,这时操作系统会剥夺此线程的CPU控制权,使其暂停执行,同时将资源让给其他的工作线程,这种线程调度方式称为阻塞。当IO操作完毕时,操作系统将这个线程的阻塞状态解除,恢复其对CPU的控制权,令其继续执行。这种IO模式就是同步式IO或阻塞式IO。

其次是了解什么是异步IO。
相应地,异步IO即非阻塞式IO则针对所有IO操作不采用阻塞的策略。当线程遇到IO操作时,不会以阻塞的方式等待IO操作的完成或数据的返回,而只是将IO请求发送给操作系统,继续执行下一条语句。当操作系统完成IO操作时,以事件的形式通知执行IO操作的线程,线程会在特定时候处理这个事件。为了处理异步IO,线程必须有事件循环,不断地检查有没有未处理的事件,依次予以处理。

阻塞模式下,一个线程只能处理一项任务,要想提高吞吐量必须通过多线程。而非阻塞模式下,一个线程永远在执行计算操作,这个线程所使用的CPU核心利用率永远是100%,IO以事件的方式通知。在阻塞模式下,多线程往往能提高系统吞吐量,因为一个线程阻塞时还有其他线程在工作,多线程可以让CPU资源不被阻塞中的线程浪费。而在非阻塞模式下,线程不会被IO阻塞,永远在利用CPU。多线程带来的好处仅仅是在多核CPU的情况下利用更多的核,而Node.js的单线程也能带来同样的好处。这就是为什么Node.js使用了单线程、非阻塞的事件编程模式。

单线程事件驱动的异步式IO比传统的多线程阻塞式IO究竟好在哪里呢?简而言之,异步式IO就是少了多线程的开销。对操作系统来说,创建一个线程的代价比较昂贵,需要给它分配内存、列入调度,同时在线程切换的时候还要执行内存换页,CPU的缓存被清空,切换回来的时候还要重新从内存中读取信息,破坏了数据的局部性。
 
当然,异步式编程的缺点在于不符合人们一般的程序设计思维,容易让控制流变得晦涩难懂,给编码和调试都带来不小的困难。习惯传统编程模式的开发者在刚刚接触到大规模的异步式应用时往往会无所适从,但慢慢习惯以后会好很多。尽管如此,异步式编程还是较为困难,不过可喜的是现在已经有了不少专门解决异步式编程问题的库(如async)。

同步IO与异步IO的比较
——————————————————————————————————————————————————————————————————
同步IO                                                                           异步IO
——————————————————————————————————————————————————————————————————
利用多线程提高吞吐量                                              单线程即可实现高吞吐量
通过时间片分割和线程调度利用多核CPU             通过功能划分利用多核CPU
需要由OS调度多线程使用多核CPU                        可以将单进程绑定到单核CPU
难以充分利用CPU资源                                             可以充分利用CPU资源
内存轨迹大,数据局部性弱                                     内存轨迹小,数据局部性强
符合线性的编程思维                                                 不符合传统编程思维

——————————————————————————————————————————————————————————————————

基于多线程的模型也有相应的解决方案,如轻量级线程等。事件驱动的单线程异步模型与多线程同步模型到底谁更好是一件非常有争议的事情,因为尽管消耗资源,后者的吞吐率并不比前者低。 

本文转载自:http://blog.csdn.net/chszs/article/details/8867174

共有 人打赏支持
invictus_lee
粉丝 1
博文 141
码字总数 21423
作品 2
徐汇
程序员
常驻内存型 PHP 框架--easySwoole

EasySwoole 是一款基于Swoole Server 开发的常驻内存型PHP框架,专为API而生,摆脱传统PHP运行模式在进程唤起和文件加载上带来的性能损失。EasySwoole 高度封装了Swoole Server 而依旧维持S...

easySwoole
2017/11/07
437
1
服务器两种高效的并发模式

一、并发编程与并发模式 并发编程主要是为了让程序同时执行多个任务,并发编程对计算精密型没有优势,反而由于任务的切换使得效率变低。如果程序是IO精密型的,则由于IO操作远没有CPU的计算速...

翼动动空
2016/09/22
118
0
WCF技术剖析之十一:异步操作在WCF中的应用(上篇)

按照操作执行所需的资源类型,我们可以将操作分为CPU绑定型(CPU Bound)操作和I/O绑定型(I/O Bound)操作。对于前者,操作的执行主要利用CPU进行密集的计算,而对于后者,大部分的操作处理...

长平狐
2012/09/04
71
0
deferred Transports Protocols 简单介绍

Twisted架构概览 Twisted是一个事件驱动型的网络引擎。由于事件驱动编程模型在Twisted的设计哲学中占有重要的地位,因此这里有必要花点时间来回顾一下究竟事件驱动意味着什么。 事件驱动编程...

浮云飘飘
2015/12/22
16
0
对浏览器端javaScript运行机制的理解

浏览器端javaScript运行机制的理解 线程 同步异步 Event-Loop 线程 Javascript语言的执行环境是"单线程"(single thread)。 所谓"单线程",就是指一次只能完成一件任务。如果有多个任务,就...

景丹
01/08
0
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

高三暑假我是怎么想开去学linux系统的

高三的时候,我有一句口头禅:“老了老了,现在做题越来越迟钝了”。当时整天日夜苦读,体重日益增加,脸色越来越黯淡,我在终于熬过了高考的时候,简直心里面乐得开了花。我终于可以去做自己...

linuxprobe16
11分钟前
0
0
Python 获得命令行参数的方法

需要模块:sys 参数个数:len(sys.argv) 脚本名: sys.argv[0] 参数1: sys.argv[1] 参数2: sys.argv[2]

编程老陆
18分钟前
0
0
链队

队列用链表来表示时,需要用两个变量来记录队列两端的变化:theFront,theBack. 根据链接方向的不同,链队有两种链接方式(其实就是链表的头插入节点和尾插入节点,头删除节点和尾删除节点)。...

Frost729
22分钟前
0
0
IDEA toString() json模板

public java.lang.String toString() {java.lang.StringBuilder builder = new java.lang.StringBuilder();#set ($i = 0)#foreach ($member in $members)#if ($i == 0)builder.appen......

Mtok
32分钟前
0
0
Dubbo内核实现之SPI简单介绍

Dubbo采用微内核+插件体系,使得设计优雅,扩展性强。那所谓的微内核+插件体系是如何实现的呢!即我们定义了服务接口标准,让厂商去实现(如果不了解spi的请谷歌百度下), jdk通过ServiceLo...

明理萝
37分钟前
0
1

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部