首页 > 其他分享 >♻️同步和异步;并行和并发;阻塞和非阻塞

♻️同步和异步;并行和并发;阻塞和非阻塞

时间:2024-06-09 17:54:38浏览次数:22  
标签:异步 通知 阻塞 并发 任务 完成 下载

概念辨析

同步(Synchronous)和异步(Asynchronous)

同步和异步关注的是任务完成的顺序和时间:

  • 同步操作意味着在执行某个任务时,必须等待这个任务完成后才能继续执行下一个任务。这通常会导致执行线程在等待任务完成时处于阻塞状态。

  • 异步操作允许执行线程在发起一个任务后,不需要等待它完成就可以继续执行后续任务。异步操作通常通过回调、事件、信号等机制来通知调用者任务已完成。

    • 状态:即监听被调用者的状态(轮询),调用者需要每隔一定时间检查一次,效率会很低。
    • 通知:当被调用者执行完成后,发出通知告知调用者,无需消耗太多性能。
    • 回调:与通知类似,当被调用者执行完成后,会调用调用者提供的回调函数。

并行(Parallel)和并发(Concurrent)

并行和并发关注的是任务如何在处理器上执行:

  • 并行指的是多个任务在多个处理器上同时执行。在并行执行中,任务之间是完全独立的,可以同时进行,从而提高效率。
  • 并发指的是多个任务在一个或多个处理器上交替执行。在单个处理器系统中,虽然任务看起来是同时执行的,但实际上处理器在不同任务间快速切换,给人一种同时执行的错觉。

阻塞(Blocking)和非阻塞(Non-blocking)

阻塞和非阻塞关注的是在等待任务完成时,线程的状态和行为:

  • 阻塞操作是指在等待操作完成时,当前线程会被挂起。例如,一个阻塞的I/O调用会导致请求它的线程停止执行,直到I/O操作完成。
  • 非阻塞操作是指即使操作尚未完成,当前线程也不会被挂起。非阻塞操作允许线程继续执行并定期检查操作是否完成。

阻塞非阻塞与同步异步的区别

同步/异步关注的是消息通知的机制,而阻塞/非阻塞关注的是程序(线程)等待消息通知时的状态。

以小明下载文件打个比方,从这两个关注点来再次说明这两组概念,希望能够更好的促进大家的理解。

同步阻塞:小明一直盯着下载进度条,到 100% 的时候就完成。

  • 同步体现在:等待下载完成通知;
  • 阻塞体现在:等待下载完成通知过程中,不能做其他任务处理;

同步非阻塞:小明提交下载任务后就去干别的,每过一段时间就去瞄一眼进度条,看到 100% 就完成。

  • 同步体现在:等待下载完成通知,但是要在;
  • 非阻塞体现在:等待下载完成通知过程中,去干别的任务了,只是时不时会瞄一眼进度条;【小明必须要在两个任务间切换,关注下载进度】

异步阻塞:小明换了个有下载完成通知功能的软件,下载完成就“叮”一声。不过小明仍然一直等待“叮”的声音(看起来很傻,不是吗)。

  • 异步体现在:下载完成“叮”一声通知;

阻塞体现在:等待下载完成“叮”一声通知过程中,不能做其他任务处理;

异步非阻塞:仍然是那个会“叮”一声的下载软件,小明提交下载任务后就去干别的,听到“叮”的一声就知道完成了。

  • 异步体现在:下载完成“叮”一声通知;
  • 非阻塞体现在:等待下载完成“叮”一声通知过程中,去干别的任务了,只需要接收“叮”声通知即可;【软件处理下载任务,小明处理其他任务,不需关注进度,只需接收软件“叮”声通知,即可】

也就是说,同步/异步是“下载完成消息”通知的方式(机制),而阻塞/非阻塞则是在等待“下载完成消息”通知过程中的状态(能不能干其他任务),在不同的场景下,同步/异步、阻塞/非阻塞的四种组合都有应用。

所以,综上所述,同步和异步仅仅是关注的消息如何通知的机制,而阻塞与非阻塞关注的是等待消息通知时的状态。也就是说,同步的情况下,是由处理消息者自己去等待消息是否被触发,而异步的情况下是由触发机制来通知处理消息者,所以在异步机制中,处理消息者和触发机制之间就需要一个连接的桥梁:

在小明的例子中,这个桥梁就是软件“叮”的声音。

同步/异步与阻塞/非阻塞效率

1 同步阻塞形式

效率是最低的,

拿上面的例子来说,就是你专心等待下载完成,什么别的事都不做。

实际程序中:就是未对fd 设置O_NONBLOCK标志位的read/write 操作;

2 异步阻塞形式

异步操作是可以被阻塞住的,只不过它不是在处理消息时阻塞,而是在等待消息通知时被阻塞。

比如select 函数,假如传入的最后一个timeout参数为NULL,那么如果所关注的事件没有一个被触发,程序就会一直阻塞在这个select 调用处。

3 同步非阻塞形式

实际上是效率低下的,

想象一下你一边干别的事情一边还需要抬头看下载完成没有,如果把干别的事情和观察下载完成情况的位置看成是程序的两个操作的话,这个程序需要在这两种不同的行为之间来回的切换,效率可想而知是低下的。

很多人会写阻塞的read/write 操作,但是别忘了可以对fd设置O_NONBLOCK 标志位,这样就可以将同步操作变成非阻塞的了。

4 异步非阻塞形式

效率更高,

因为等待下载完成是你(等待者)的事情,而通知你则是电脑(消息触发机制)的事情,程序没有在两种不同的操作中来回切换。

至此,关于进程线程、同步异步、阻塞非阻塞、并发并行已经讲的差不多了,有讲的不好的地方请大佬指出。同时也谢谢网上大佬的文章帮助我理解了这些概念。

参考来源

https://cloud.tencent.com/developer/article/1592939

标签:异步,通知,阻塞,并发,任务,完成,下载
From: https://www.cnblogs.com/banon/p/18239826

相关文章

  • 互联网大厂的缓存策略:抵抗超高并发的秘密武器
    大家好,我是冰河~~最近,有小伙伴私信我:冰哥,我最近出去面试,面试官问我如何设计缓存能让系统在百万级别流量下仍能平稳运行,我当时没回答上来。接着,面试官问我之前的项目是怎么使用缓存的,我说只是缓存了一些数据。当时确实想不到缓存还有哪些用处,估计这次面试是挂了。冰哥,你可以给我讲......
  • Java虚拟机,并发与并行的并存
    ZYCEONGAO:场景:尽管多核处理器提供了并行执行的物理条件,但并非所有场景都能够或应该完全并行化。 线程数超过核心数:当应用程序创建的线程数量超过了处理器的核心数,操作系统会采用类似单核处理器上的时间片轮转策略,轮流将线程分配到各个核心上执行。这意味着,即使在多核环......
  • spring security中对并发登录的处理
    本文记录的springsecurity中对并发登录的处理,是基于使用session进行登录的场景,并且只适用于单体部署的场景一、session管理策略接口SessionAuthenticationStrategy针对同一个账号多次登录的问题,springsecurity抽象出了一个接口来处理同一个用户的多个sessionpublicinterf......
  • 【建站教程】Ubuntu结合宝塔面板本地部署Inis博客并发布公网
    ......
  • kettle从入门到精通 第六十六课 ETL之kettle kettle阻塞教程,轻松获取最后一行数据,so e
    场景:ETL沟通交流群内有小伙伴反馈,如何在同步一批数据完成之后记录下同步结果呢?或者是调用后续步骤、存储过程、三方接口等。解决:使用步骤Blockingstep进行阻塞处理即可。1、下面的demo演示从表t1同步数据至表t2(t1表中有三条数据,t2为空表,两个表表结构相同),然后数据同步完毕之后进......
  • 另一个Java基于阻塞的定时消费内存队列(依赖guava)
    本文的代码是对一个Java基于阻塞的定时消费内存队列-Jackie_JK-博客园(cnblogs.com)方法的改进,完善了包装以及部分细节,非jdk21可能需要更换线程池类型。消费类型:@Getter@AllArgsConstructorpublicenumPushType{ELASTIC,SQL,;}队列参数枚举:@Getter@AllAr......
  • C#异步编程是怎么回事(番外)
    在上一篇通信协议碰到了多线程,阻塞、非阻塞、锁、信号量...,会碰到很多问题。因此我感觉很有必要研究多线程与异步编程。首先以一个例子开始我说明一下这个例子。这是一个演示异步编程的例子。输入job[name],在一个同步的Main方法中,以一发即忘的方式调用异步方法StartJob()。......
  • GuzzleHttp 并发发起 http 请求
    GuzzleHttp并发发起http请求‍系统中需要调用百度翻译接口做多语言支持,百度翻译对于不同的认证给予了不同的权益,通用文本翻译API标准版、高级版、尊享版的不同服务权益如下:标准版高级版尊享版QPS=1支持28个语种互译单次最长请求1000字符免费调用量5万字符/月QPS=......
  • FastAPI-4:异步、并发和Starlette
    4异步、并发和Starlette本章关注FastAPI的底层Starlette库,尤其是它对异步处理的支持。在概述了Python中“同时做更多事情”的多种方法后,您将看到Python中较新的async和await关键字是如何融入Starlette和FastAPI的。4.1StarletteFastAPI的大部分网络代码都基于TomChristie......
  • 高并发下使用Redis分布式锁确保接口执行唯一性【重点】
    摘要:本文将介绍如何使用Redis分布式锁来确保在高并发环境下,确保某个接口只有一个线程能够执行。通过使用Redis的SETNX命令,我们可以实现一个简单的分布式锁,从而避免多个线程同时访问共享资源。一、背景在高并发的系统中,为了保证数据的一致性和完整性,我们经常需要对某些接口......