前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >专栏 >自古以来,同步/异步都是八股文第一章

自古以来,同步/异步都是八股文第一章

作者头像
有态度的马甲
发布于 2023-09-18 02:53:59
发布于 2023-09-18 02:53:59
22800
代码可运行
举报
文章被收录于专栏:精益码农精益码农
运行总次数:0
代码可运行
成文耗时2小时,阅读8min,有用指数拉满。

好久没上线了,今天记录编程中老掉牙的几个关键术语,一个言简意赅的术语定义包含主谓宾定状补, 我们应从貌似雷同的术语中体会到不同术语的表象行为、侧重点。

下面给出的3对技术术语,都是很核心、易混淆的概念点,但是多少还是有些表象、侧重点的不同。

书读百遍其义自见, 请关注最下方给出的微软官方技术文献, 自勉!!

1. 同步/异步、 阻塞/非阻塞

阻塞操作不等于同步,非阻塞操作也不等于异步。实际上,它们之间并没有直接的联系。

先说同步,这个很简单,就是按照代码来顺序执行。

比如下面这段伪代码:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
local res, err  = query-mysql(sql)
local value, err = query-redis(key)

在同一请求连接中,如果要等 MySQL 的查询结果返回后,才能继续去查询 Redis,那就是同步;

如果不用等 MySQL 的返回,就能继续往下走,去查询 Redis,那就是异步。

完全不care MYSQL的查询结果,也不是业务想要的,一般的实践是query-mysql函数快速返回一个awaitable对象,通过状态查询、事件通知的方式拿到异步行为的结果。

再来说说非阻塞,这是一个很容易和“异步”混淆的概念。

这里我们说的“阻塞”,特指阻塞操作系统线程

我们继续看上面的例子,假设查询 MySQL 需要1s 的时间,如果在这1s 内,操作系统的资源(CPU)是空闲着并傻傻地等待返回,那就是阻塞;

如果 CPU 趁机去处理其他连接的请求,那就是非阻塞。

总体而言:

同步/异步[1]虽然表现为函数调用,实际宏观上描述了信息对齐方式, 异步调用/异步通信/异步任务均表现为发出通信动作后即刻返回,通过状态通知、回调函数来拿到通信结果。

阻塞/非阻塞关注的是应用程序在等待数据返回的状态问题:在得到结果之前,cpu若傻傻等待是阻塞(被挂起)。

.NET异步编程的三种套路[2]

  1. (1). 基于任务的异步模式 (TAP), 主流推荐
  2. (2). 基于事件的异步模式 (EAP), 过时不推荐
  3. (3). 异步编程模型 (APM) 模式(也称为 IAsyncResult 模式), 过时不推荐

2,3已经不被推荐(2,3其实很贴近异步的行为认知),目前主流推荐的TAP async/await语法糖,以同步姿势简化了异步编程, 但是语法糖也让我们不容易理解异步的本质:async/await语法糖具备传染性,导致async/await在整个代码结构泛滥使用,在被传染的async/await层级, 根本不体现通信交互,弱化了开发者对于最底层是异步通信的认知。

微软喜欢搞拖拽控件、语法糖给到开发者,让我们沉迷于便利的开发体验,忽视了朴素的核心本质。

2. 事件/消息[3]

事件是对条件或状态更改的轻量级通知。

  • • 事件的发布者对如何处理事件没有期望。
  • • 事件的使用者决定如何处理通知。
  • • 事件报告状态变化并且是可操作的, 这是一个信号,消费者只需要知道发生了什么。事件数据包含关于发生了什么事情的信息,但不包含触发事件的数据。 例如,事件通知使用者文件已创建,它可能有关于文件的一般信息,但它没有文件本身。
  • • 事件可以是离散的个体,也可以是一系列事件的一部分。一系列事件报告了一种状况,并且是可分析的。这些事件是按时间顺序排列并相互关联的,消费者可通过序列事件来分析发生了什么。

消息是由服务生成的原始数据,将在其他地方使用或存储 。

  • • 消息包含触发消息管道的数据。
  • • 消息的发布者对于消费者如何处理消息有一个期望。双方之间存在一份契约。例如,发布者发送带有原始数据的消息,并期望消费者从该数据创建文件,并在工作完成时发送响应。
3. 委托/事件[4]

委托更像一个类的一个属性,只不过属性值是函数,公开的委托可以像类属性一样,自由赋值。

在众多语言中,委托与闭包密切相关。 传送门: 全网最通透的“闭包”认知 · 跨越语言

和委托类似,事件也是后期绑定机制。实际上,事件是建立在对委托的语言支持之上。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
 In the .NET class library, events are based on the EventHandler delegate and the EventArgs base class.  
public delegate void EventHandler(object? sender, EventArgs e);

后期绑定机制:组件通过调用可在运行时识别的方法进行通信。它们都支持单个和多个订阅服务器方法。这称为单播和多播支持。

两者均支持用于添加和删除处理程序的类似语法,引发事件和调用委托也是相同的调用语法。它们甚至都支持与 ?. 运算符结合的 Invoke() 语法。

使用委托/事件有一些考量:

(1). 若侦听器可选,更倾向事件

A组件引发了事件,也许并不引发其他组件的连锁反应,也就是没有预置侦听器,这时虽然用委托也行,但是更倾向用事件。

(2). 事件只能由定义事件的组件自行触发 ,而不能由外部触发。

包含事件的类以外的类只能添加和删除事件侦听器;只有包含事件的类才能引发事件。还是那句话,事件更强调组件在满足条件或自身状态变更时触发。

(3). 事件不care侦听器的返回值

与1相关,因为事件的引发者本身也不care有没有侦听器。

结语

搬砖多年,越来越体会到精准理解术语的重要性, 不管是日常技术撕逼,还是阅读文献,潜意识都要留意你认定的术语定义是不是与对方要表露的定义一致。

上面三对概念:冥冥中存在某种微妙联系。

同步/异步:描述了信息的对齐方式,如果是异步会即时返回,使用状态通知、回调事件(这个回调事件对应事件/消息的事件概念)来获得操作结果。

事件/消息:描述了信息的侧重点, 事件强调了某组件在满足某种条件、时间点而触发了某次行为,不care是否有消费方对这个行为产生了连锁反应。 消息是生产方要传递的原始数据,消息生产方对消息被消费是有期待的(存在消息格式便于消费方理解)。

委托/事件:更接近于事件的技术实现,事件是基于委托实现,事件更强调内生引发、不care是否有外部侦听动作,委托可认为是类属性。

引用链接

[1] 同步/异步: https://learn.microsoft.com/en-us/dotnet/csharp/asynchronous-programming/ [2] .NET异步编程的三种套路: https://learn.microsoft.com/zh-cn/dotnet/standard/asynchronous-programming-patterns/ [3] 事件/消息: https://learn.microsoft.com/en-us/azure/service-bus-messaging/compare-messaging-services [4] 委托/事件: https://learn.microsoft.com/zh-cn/dotnet/csharp/distinguish-delegates-events

年终总结:2021技术文大盘点 | 打包过去,面向未来

项目总结:麻雀虽小,五脏俱全

理念总结:实话实说:只会.NET,会让我们一直处于鄙视链、食物链的下游

云原生系列: 什么是云原生?

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2023-06-27 20:34,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 精益码农 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
C#:异步编程中的 async 和 await
async 和 await 在 C# 5.0 就已经引入了,用来处理异步编程,但之前用的相对较少,现在在 dotNet Core 时代,已经使用的非常普遍,很多的开源组件中提供了大量的后缀为 Async (异步)的方法。本文就简单讲讲 async 和 await。
oec2003
2020/11/19
2.7K0
C#:异步编程中的 async 和 await
理解同步异步与阻塞非阻塞——傻傻分不清楚的终极指南
同步异步与阻塞非阻塞这两组概念在 IO 场景下非常常见,由于他们在表现出来的效果上很相似,很容易造成混淆和困扰,要想理清楚这两组概念首先需要认识到这两组概念强调的是不同维度的事。
菜皮日记
2024/08/05
1230
异步编程
异步编程.png 异步编程 函数式编程 高阶函数 高阶函数则是可以把函数作为参数,或是将函数作为返回值的函数, 除了通 常意义的函数调用返回外,还形成了一种后续传递风格 在自定义事件实例中,通过为相同事件注册不同的回调函数,可以很灵活地处理业务逻辑 偏函数用法 通过指定部分参数来产生一个新的定制函数的形式就是偏函数 异步编程的优势与难点 优势 Node带来的最大特性莫过于基于事件驱动的非阻塞I/O模型 只要合理利用Node的异步模型与V8的高性能,就可以充分 发挥CPU和I/O资源的优势 难点 try/c
李才哥
2021/02/28
7810
异步编程
C#异步有多少种实现方式?
  微信群里的一个提问引发的这个问题,有同学问:C#异步有多少种实现方式?想要知道C#异步有多少种实现方式,首先我们要知道.NET提供的执行异步操作的三种模式,然后再去了解C#异步实现的方式。
追逐时光者
2023/05/11
4990
深入浅析Node.js中的异步
以点菜吃饭为例子:去饭堂点菜吃饭需要排队等待,在这个过程中,阿姨每次只能接待一个人,“点菜-阿姨抖勺装菜-把饭菜给到你”这个过程中阿姨并不能接收其他人的点菜,这个就是阻塞 I/O;而去餐馆点菜吃饭,去到餐馆就可以跟服务员你要吃番茄炒蛋,服务员记下来之后交给后厨,这时候来了另一桌人就把服务员招呼过去说想吃小龙虾,也就是说,在把菜给你上上来之前服务员接收了其他人的点菜,那这个就是非阻塞型 I/O。
conanma
2022/01/05
1.3K0
特皮技术团队:一年经验菜鸟前端眼中的异步编程
前端开发必不可少,什么是异步编程 由于javascript语言是一门“单线程”的语言,所以,javascript就像一条流水线,仅仅是一条流水线而已,要么加工,要么包装,不能同时进行多个任务和流程。 而作为前端开发,在面试与工作中相信大家一定被问过或经常需要用到异步编程,那么什么是异步编程呢? 首先我们先区分一下什么是同步编程,什么是异步编程。 同步编程:我们都知道代码的执行顺序是自上而下执行的,那么同步就是需要每一个任务都完成以后再去执行下一个任务,执行顺序与排列顺序是一致的。坏处,只要有一个任务耗时很长
Peter谭金杰
2020/08/05
5060
特皮技术团队:一年经验菜鸟前端眼中的异步编程
同步与异步概念解析
同步指的是在同一进程中,任务按照编写的顺序一个接一个执行。如果任务一和任务二是同步关系,那么任务二必须等待任务一完全结束后才能开始执行。这种执行方式是阻塞的,后续任务必须等待前一个任务完成。
用户11397231
2024/12/10
1650
看过这么多爆文,依旧走不好异步编程这条路?​
本文带大家抓住异步编程async/await语法糖的牛鼻子: SynchronizationContext。
有态度的马甲
2021/06/08
8670
看过这么多爆文,依旧走不好异步编程这条路?​
准确理解阻塞、非阻塞、同步、异步
但是你还真别小看这几个基础概念,由于网上的说法五花八门,众说纷纭,导致了不同的人对这几个概念的理解差异还有点大,错误理解和云里雾里的人大有人在。有的人还会把阻塞/非阻塞与同步/异步混合起来理解,认为阻塞=同步、非阻塞=异步。
用户6901603
2024/03/11
1380
准确理解阻塞、非阻塞、同步、异步
深入理解Python异步编程(上)
彻底理解异步编程是什么、为什么、怎么样。深入学习asyncio的基本原理和原型,了解生成器、协程在Python异步编程中是如何发展的。
SeanCheney
2018/08/16
7.1K0
深入理解Python异步编程(上)
关于JavaScript中的回调看这篇就够了
回调函数是每个前端程序员都应该知道的概念之一。回调可用于数组、计时器函数、promise、事件处理中。
疯狂的技术宅
2021/01/13
9960
.NET Core多线程 (2) 异步 - 上
举个例子,在高峰期去餐厅吃饭,会先排队拿个小票,然后去逛一下玩玩,等到排到时会被通知就餐,这时再回到餐厅就可以点餐了。
Edison Zhou
2023/08/09
3050
.NET Core多线程 (2) 异步 - 上
细说JS异步发展历程
所谓同步,就是在发出一个"调用"时,在没有得到结果之前,该“调用”就不返回。但是一旦调用返回,就得到返回值了。换句话说,就是由“调用者”主动等待这个“调用”的结果。此调用执行完之前,阻塞之后的代码执行。
胡哥有话说
2019/09/17
2.4K0
细说JS异步发展历程
JavaScript 异步编程
完整高频题库仓库地址:https://github.com/hzfe/awesome-interview
HZFEStudio
2021/10/30
1K0
谈谈ES6前后的异步编程
Javascript 语言的执行环境是“单线程”的,如果没有异步编程,根本没法用,非卡死不可。
张炳
2019/08/02
8140
C#8.0宝藏好物Async streams
.NET诞生之初,就通过IEnumerable、IEnumerator提供迭代能力, 前者代表具备可枚举的性质,后者代表可被枚举的方式。 (看你骨骼惊奇,再送你一本《2021年了,IEnumerable、IEnumerator接口还傻傻分不清楚?》) 如果你真的使用强类型IEnumerable/IEnumerator来产生/消费可枚举类型,会发现要写很多琐碎代码。
有态度的马甲
2021/04/21
9870
C#8.0宝藏好物Async streams
JavaScript 中如何进行异步编程
JavaScript语言的一大特点就是单线程,也就是说,同一个时间只能做一件事。那么,为什么JavaScript不能有多个线程呢?这样能提高效率啊。
江米小枣
2020/06/16
8130
JavaScript 中如何进行异步编程
.Net异步编程模式
异步编程模式的英文全称是The Asynchronous Programming Models,简称是APM。简单说明一下为什么要异步编程,以及异步编程带来的好处有:
小蜜蜂
2019/07/15
7480
面试必备:C#多线程技术
进程是应用的执行实例,可狭义理解为一个应用程序就是一个进程。启用一个应用程序时就是启动了一个进程。
郑子铭
2023/08/30
4720
面试必备:C#多线程技术
你真的懂异步编程吗?
在JS 代码中,异步无处不在,Ajax通信,Node中的文件读写等等等,只有搞清楚异步编程的原理和概念,才能在JS的世界中任意驰骋,随便撒欢;
西岭老湿
2021/01/12
8560
你真的懂异步编程吗?
相关推荐
C#:异步编程中的 async 和 await
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档