您当前的位置:首页> 滚动 >正文
什么是并发?《Swift异步与并发编程》读书笔记(一

2023-08-16 13:16:56     来源 : 哔哩哔哩

一般的结构化编程吸取了Goto式非结构化编程的经验,通过控制流遵守通用的约定,建立编程结构。

而并发的发展历程也同上基本一致。


(资料图片仅供参考)

由于多线程开发中的长耗时特征,在大型系统中,非结构化的并发编程在运行时跟踪单元操作、遭遇内存冲突时遇到的挑战更大,更难以解决,也就更迫切地需要一套编程理论来作为共识性的指导,也就有了结构化并发。

结构化并发

其可以概括为:

『即使进行并发操作,也要保证控制流路径的单一入口和单一出口。程序可以产生多个控制流来实现并发,但是所有的并发路径在出口时都应该处于完成 (或取消) 状态,并合并到一起。』

好处是:使抽象层得以有效运作。在这一结构下编码时要可以拍着胸脯保证代码不会跳转到结构外,是严格『自包含』的。

同步与异步

找不同!

是的,

和字面意思相反,同步函数返回、完成之前,运行它的线程无法执行其他操作。

同步 synchronous异步 asynchronous

UIKit和SwiftUI都不是线程安全的:

对于用户输入的处理和UI的绘制,必须在与主线程绑定的main runloop中进行。

为避免长耗时操作将主线程堵塞导致用户输入无响应、UI卡顿,最常见的应对办法是将同步操作转换成异步操作:

开辟后台线程运行长耗时操作,然后在操作结束时提供运行在主线程的回调。

串行与并行

两者都是执行操作的顺序或方式;同步操作一定以串行方式执行。   串行:同一时刻的多个线程之间一定是为同一个操作使用,不会另作其他事,甚至只在同一个线程内逐条执行。异步操作则主要以并行方式执行,线程间通信时会以串行方式执行,也就是既能并行也能串行。    并行:同一时刻的多个线程一并执行多个操作。为降低理解并发的难度,提并发时,一般都限定在『异步和并行代码的组合』这个简化版的意义。

并发编程的困难大致上有两个:

如何确保顺序执行;————逻辑正确性

如何确保运算资源调度、访问不冲突。————内存安全性

异步函数

为了化解并发编程的如上两个困难,引入异步函数

func loadSignature() async throws -> String {

fatalError("暂未实现")

}

在返回箭头前加上 async关键字就可以把函数声明为异步函数。

throw关键字类似地,该关键字帮助编译器确保两件事:

它允许在函数体内部(正确地)使用 await关键字;

它要求其他来源在调用这个函数时,使用 await 关键字。

await代表了函数在此处可能会放弃当前线程,它是程序的潜在暂停点。

Task 任务

对于同步函数来说,线程决定了它的执行环境。

对于异步函数来说,任务决定了它的执行环境。

『Swift 并发编程中,结构化并发需要依赖异步函数,而异步函数又必须运行在某个任务上下文中,因此可以说,想要进行结构化并发,必须具有任务上下文。

实际上,Swift 结构化并发就是以任务为基本要素进行组织的。』

简单地使用 就可以让我们获取一个任务执行的上下文环境,它接受 `async` 标记的闭包。而且能继承当前任务上下文的优先级等特性,创建一个新的任务树的根节点。我们可以在其中使用异步函数,用法类似于 Task { 异步代码 }

> Task的要点

> 创建、组织、检查和取消任务

> 一个任务具有它自己的优先级和取消标识,它可以拥有若干个子任务并在其中执行异步函数。

> 无论是正常完成还是抛出错误,子任务会将结果向上报告给父任务,在所有子任务完成之前 (不论是正常结束还是抛出),父任务是不会完成的。

> 当一个父任务被取消时,这个父任务的取消标识将被设置,并向下传递到所有的子任务中去。

Task Group 任务组

在任务运行上下文中,或具体来说——

在某个异步函数中,我们可以通过await withTaskGroup 为当前的任务添加一组结构化的并发子任务。

这些子任务在被添加后立刻开始执行,最终在离开group的作用域时再汇集到一起。

async let 异步绑定

类似于 let地, async let定义一条局部的不变变量,并通过等号右侧的表达式来初始化该不变变量。

不同的是,该初始化表达式必须是异步函数的调用,通过将其绑定到该不变变量上,在当前 Task上下文创建一道并发执行的子任务并立刻加以执行。

async let赋值之后将立刻执行,即使在 await之前执行就已经完成,其结果依然可以等到 await语句时再进行求值。

新建一个任务根节点不同,async let所创建的子任务是任务树上的叶子节点。

任务组和异步绑定的对比

async let可以理解成任务组如 withTaskGroup的语法糖,但是异步绑定并不能动态地表达任务的数量。

『一个大致的使用原则是,如果我们需要比较「严肃地」界定结构化并发的起始,那么用任务组 Task Group 的闭包将它限制起来,并发的结构会显得更加清晰;

而如果我们只是想要快速地并发开始少数几个任务,并减少其他模板代码的干扰,那么使用 async let 进行异步绑定,会让代码更简洁易读。』

标签:

X 关闭

行业要闻
土巴兔公司持续盈利能力存疑 毛利率超90%比肩茅台净利率仅10%

土巴兔公司持续盈利能力存疑 毛利率超90%比肩茅台净利率仅10%

6月底前河南省实现“场所码”全覆盖 升级后的“场所码”有啥功能

6月底前河南省实现“场所码”全覆盖 升级后的“场所码”有啥功能

公安部推行新车上牌新规 便利群众快捷上牌

公安部推行新车上牌新规 便利群众快捷上牌

北京市经信局公布今年第三批北京市“专精特新”中小企业名单

北京市经信局公布今年第三批北京市“专精特新”中小企业名单

“520”迎婚姻登记高峰!深圳市民政局:高峰日扎堆登记可能影响体验感

“520”迎婚姻登记高峰!深圳市民政局:高峰日扎堆登记可能影响体验感

北京市东城区41条措施落地 2790家中小微企业享受政策支持

北京市东城区41条措施落地 2790家中小微企业享受政策支持

地球上最幸福的人!56岁非洲建筑师获普利兹克建筑奖

地球上最幸福的人!56岁非洲建筑师获普利兹克建筑奖

新疆阿克苏地区库车市发生4.1级地震 震源深度21千米

新疆阿克苏地区库车市发生4.1级地震 震源深度21千米

从东北到西北 他在“军垦第一城”规划着城建未来

从东北到西北 他在“军垦第一城”规划着城建未来

西藏米林“家庭农场”:引领种植产业 助力乡村振兴

西藏米林“家庭农场”:引领种植产业 助力乡村振兴