为了账号安全,请及时绑定邮箱和手机立即绑定

异步与非阻塞

异步与非阻塞

Qyouu 2019-11-04 14:38:00
异步调用和非阻塞调用有什么区别?还在阻塞和同步调用之间(请提供示例)?
查看完整描述

3 回答

?
明月笑刀无情

TA贡献1828条经验 获得超4个赞

在许多情况下,它们是同一事物的不同名称,但是在某些情况下,它们是完全不同的。因此,这取决于。术语并不是在整个软件行业中以完全一致的方式应用。

例如,在经典套接字API中,非阻塞套接字是一个简单地立即返回特殊“错误块”错误消息的套接字,而阻塞套接字会被阻塞。您必须使用单独的函数,例如select或,poll以找出何时是重试的好时机。

但是,异步套接字(Windows套接字支持)或.NET中使用的异步IO模式更为方便。您调用一个方法来开始操作,框架完成后会回调您。即使在这里,也存在基本差异。异步Win32套接字通过传递Window消息将其结果“编组”到特定的GUI线程,而.NET异步IO是自由线程的(您不知道将在哪个线程上调用回调)。

因此,它们并不总是意味着同一件事。为了说明套接字示例,我们可以说:

  • 阻塞和同步的含义相同:调用API,它将挂起线程,直到得到某种答案并将其返回给您为止。

  • 非阻塞意味着,如果无法快速返回答案,则API会立即返回错误并执行其他操作。因此,必须有一些相关的方式来查询API是否已准备好被调用(即,以一种有效的方式模拟等待,以避免在紧密循环中进行手动轮询)。

  • 异步意味着API总是立即返回,并且已经开始了“后台”工作来满足您的请求,因此必须有一些相关的方法来获取结果。


查看完整回答
反对 回复 2019-11-04
?
慕桂英4014372

TA贡献1871条经验 获得超13个赞

  • 异步是指并行完成的事情,也就是说是另一个线程。

  • 非阻塞通常指轮询,即检查给定条件是否成立(套接字可读,设备具有更多数据,等等)。


查看完整回答
反对 回复 2019-11-04
?
神不在的星期二

TA贡献1963条经验 获得超6个赞

同步/异步是描述两个模块之间的关系。

阻塞/非阻塞是描述一个模块的情况。


例如:

模块X:“ I”。

模块Y:“书店”。

X问Y:您有一本书名为“ c ++入门”吗?


1)阻止:Y回答X之前,X一直在那里等待答案。现在,X(一个模块)正在阻塞。X和Y是两个线程或两个进程还是一个线程或一个进程?我们不知道。


2)非阻塞:在Y回答X之前,X只是离开那里做其他事情。X可能每两分钟回来一次,以检查Y是否完成工作?还是X在Y打电话给他之前不会回来?我们不知道 我们只知道X在Y完成工作之前可以做其他事情。X(一个模块)在这里是非阻塞的。X和Y是两个线程还是两个进程或一个进程?我们不知道。但是我们确定X和Y不能是一个线程。


3)同步:在Y回答X之前,X一直在那里等待答案。这意味着X直到Y完成其工作才能继续。现在我们说:X和Y(两个模块)是同步的。X和Y是两个线程或两个进程还是一个线程或一个进程?我们不知道。


4)异步:在Y回答X之前,X离开那里,X可以做其他工作。X在Y打电话给他之前不会回来。现在我们说:X和Y(两个模块)是异步的。X和Y是两个线程还是两个进程或一个进程?我们不知道。但是我们确定X和Y不能是一个线程。




请注意上面两个大胆的句子。为什么2)中的粗体句子包含两种情况,而4)中的粗体句子仅包含一种情况?这是非阻塞和异步之间区别的关键。


这是有关非阻塞和同步的典型示例:


// thread X

while (true)

{

    msg = recv(Y, NON_BLOCKING_FLAG);

    if (msg is not empty)

    {

        break;

    }

    sleep(2000); // 2 sec

}


// thread Y

// prepare the book for X

send(X, book);

您可以看到这种设计是非阻塞的(可以说,大多数情况下,该循环都在做些废话,但是在CPU看来,X正在运行,这意味着X在无阻塞的情况下),而X和Y是同步的,因为X可以在将书从Y手中拿走之前,不要继续做任何其他事情(X不能跳出循环)。

通常,在这种情况下,使X阻塞要好得多,因为非阻塞会在愚蠢的循环上花费大量资源。但是此示例可以帮助您理解以下事实:非阻塞并不意味着异步。


这四个词确实容易使我们感到困惑,我们应该记住的是,这四个词用于建筑设计。了解如何设计好的体系结构是区分它们的唯一方法。


例如,我们可以设计这种架构:


// Module X = Module X1 + Module X2

// Module X1

while (true)

{

    msg = recv(many_other_modules, NON_BLOCKING_FLAG);

    if (msg is not null)

    {

        if (msg == "done")

        {

            break;

        }

        // create a thread to process msg

    }

    sleep(2000); // 2 sec

}

// Module X2

broadcast("I got the book from Y");



// Module Y

// prepare the book for X

send(X, book);

在这里的例子中,我们可以说


X1是非阻塞的

X1和X2是同步的

X和Y是异步的

如果需要,您还可以用四个词描述在X1中创建的那些线程。


更重要的是:什么时候使用同步而不是异步?我们什么时候使用阻塞而不是非阻塞?


为什么Nginx是非阻塞的?为什么要阻止Apache?


为了做出一个好的选择,您必须分析您的需求并测试不同体系结构的性能。没有适合各种需求的架构。


查看完整回答
反对 回复 2019-11-04
  • 3 回答
  • 0 关注
  • 316 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信