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

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

本程序中的代码大部分是示意代码,不能真正运行。

1、阻塞:阻塞是指当前线程被堵住了,不能继续往下执行了,就被操作系统挂起了。

阻塞的对象是当前线程,而不是IO被阻塞了;外部资源(通常是IO)使得当前线程被挂起才叫阻塞,内部程序执行的再慢也不叫阻塞,比如一个JPEG.Encode(),虽然这个函数的执行很慢,但它仍然在执行,不叫阻塞。阻塞的核心表现是等待,什么事情都做不了,只有等待。

2、非阻塞:调用外部资源,不管结果如何,不会阻挡线程的继续执行。

3、同步:“调用”然后得到“结果”。可能立即得到结果,可能等待一毫秒,也可能等待一辈子,反正结果必须紧随其后。

同步的概念关键在于结果必须紧随调用者之后到来,可以有等待,也可以没有等待,不管有没有等待,同步跟阻塞都没有必然关系。比如同步非阻塞接口Socket.NoBlockRecv(),一旦调用它,有数据就返回数据,没数据就返回空数据或错误,反正不会让你等待。

还有一个同步非阻塞的例子是协程,协程是一种巧妙的机制,既实现了同步返回结果(不像Socket.NoBlockRecv()没有数据就返回空数据或错误当结果),又不会阻塞当前线程。下面是Unity3D的协程的例子:

   IEnumerator WaitAndDebug()
    {
          //打印一句日志
        Debug.Log("WaitAndDebug start" + Time.time);
        //这句的执行要花费5秒,但5秒时间段内,当前线程可以干其它事,同步非阻塞。
        yield return new WaitForSeconds(5);
        //5秒后再打印一句日志
        Debug.Log("WaitAndDebug done" + Time.time);
    }

4、异步:“调用”,有“结果”再通知我。异步跟同步的区别是,结果返回时间点跟调用发起时间点没有强制关系,调用者是被动得到结果的,不是主动等待结果的。

5、Reactor:响应模式,我是被动的,外部要我干什么,我就干什么,受外部驱动。Reactor模式虽然起源于网络IO设计,但这种思想是通用的。基于Reactor模式的网络IO是这样的:

首先声明要监听哪些事件
socket.addEventHandler("receiveEvent",  receiveHandler);
socket.addEventHandler("canSendEvent",  canSendHandler);

function receiveHandler()
{
     socket.receive();//IO告诉我有数据来了,我才去接收数据,同步的
}

function canSendHandler()
{
     socket.send();//IO告诉我它不繁忙了,可以发送数据了,我才去发数据,同步的
}

Reactor的核心是被动响应,程序响应IO事件,具体的收发操作还是需要程序自己去完成,虽然这期间没有阻塞,但收发操作还是同步的。

6、Proactor:主动模式,我是主动的,我想什么时候干,就什么时候干,不受外部驱动。基于Proactor模式的网络IO是这样的:

socket.addEventHandler("receiveSuccessEvent",  receiveSuccessHandler);
socket.addEventHandler("sendSuccessEvent", sendSuccessHandler);

//不用关心IO是否繁忙,发就是了,成功了会通知我的,通过sendSuccessEvent事件
socket.sendAsync(data);
//不用关心有没有数据,我想何时接收就接收,如果我不执行接收,就永远不会触发receiveSuccessEvent事件
socket.receiveAsync();

function receiveSuccessHandler(data)
{
    log("received data");//IO已经把数据接收好了,然后通知我,异步的
}

function sendSuccessHandler()
{
     log("send data success");//IO把数据发送成功了,然后通知我,异步的
}

举个形象的例子:去银行取款。
Reactor:拿号,某个柜台空闲了就通知我去取款,我还是必须坐到柜台前取款,取款过程还是同步的。
Proactor:拿号,告诉大堂经理我要取款,款到了,大唐经理送到我手中,取款过程是异步的。

以上都是个人理解,如果有错误的地方,欢迎大家指正。



版权声明:本文为博主原创文章,未经博主允许不得转载。

相关文章推荐

关于Reactor和Proactor的区别

系统I/O 可分为阻塞型, 非阻塞同步型以及非阻塞异步型。 阻塞型I/O意味着控制权只到调用操作结束了才会回到调用者手里。 非阻塞同步是会立即返回控制权给调用者的。调用者不需要等等,它从调用的函...

同步异步阻塞非阻塞

  • 2015-04-29 10:12
  • 380KB
  • 下载

怎样理解阻塞非阻塞与同步异步的区别?

“阻塞”与”非阻塞”与”同步”与“异步”不能简单的从字面理解,提供一个从分布式系统角度的回答。1.同步与异步 同步和异步关注的是消息通信机制 (synchronous communication/ ...

IO阻塞、非阻塞、同步、异步理解

http://blog.csdn.net/historyasamirror/article/details/5778378 http://www.zhihu.com/question/19732...

深入理解同步/异步与阻塞/非阻塞区别

同步与异步 首先来解释同步和异步的概念,这两个概念与消息的通知机制有关。 举个例子,比如一个用户去银行办理业务,他可以自己去排队办理,也可以叫人代办,办完之后再告知用户结果...

怎样理解阻塞非阻塞与同步异步的区别?

作者:严肃 链接:https://www.zhihu.com/question/19732473/answer/20851256 来源:知乎 著作权归作者所有。商业转载请联系作者获得授权,非商业...

同步、异步、阻塞和非阻塞的理解

阻塞     《node.js开发指南》是这样定义的:线程在执行中如果遇到(I/O 操作)如磁盘读写或网络通信,通常要耗费较长的时间,这时操作系统会剥夺这个线程的 CPU 控制权,使其暂停执行,...

阻塞与非阻塞,同步与异步的理解

“阻塞”与"非阻塞"与"同步"与“异步"不能简单的从字面理解,提供一个从分布式系统角度的回答。 1.同步与异步 同步和异步关注的是消息通信机制 (synchronous communication...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

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