Concurrency in Swift学习笔记-初识

深入理解代替单纯记忆
并发模型Concurrency自Swift 5.5版本引入

读完官方《The Swift Programming Language》中的Concurrency部分后,感觉对其中的很多概念并没有深入的讲解,也没办法容易地上手写代码

于是查阅了其他的资料,希望对整体的设计理念和实践有清晰的认识,方便后应用到项目中

无论是Concurrency,还是其他语言的并发工具,都是为了解决并发中的两个问题:

  1. 如何确保不同运算运行步骤之间的交互或通信可以按照正确的顺序执行。
  2. 如何确保运算资源在不同运算之间被安全地共享、访问和传递

概念虽多但职责清晰

各模块职责清晰

  • 异步函数(Asynchronous Functions):提供语法工具,使用更简洁和高效的方式,表达异步行为
  • 结构化并发(Structured Concurrency):提供并发的运行环境,负责正确的函数调度、取消和执行顺序以及任务的生命周期
  • actor 模型:提供封装良好的数据隔离,确保并发代码的安全

异步函数

简单讲,就是用async标记的函数

csharp 复制代码
// 异步函数
func loadSignature() async throws -> String? {
	let (data, _) = try await URLSession.shared.data(from: someURL)
	return String(data: data, encoding: .utf8)
}
// 执行函数
let signature = await loadSignature()
  • 执行该函数时必须在前面加await关键字,代表了函数在此处可能会放弃当前线程 ,它是程序的潜在暂停点(Suspension Points)
  • 放弃线程的能力,意味着异步方法可以被"暂停",这个线程可以被用来执行其他代码。如果这个线程是主线程的话,那么界面将不会卡顿
  • 被 await 的语句将被底层机制分配到其他合适的线程,在执行完成后,之前的"暂停"将结束,异步方法从刚才的 await 语句后开始,继续向下执行

异步函数的 async 关键字会帮助编译器确保两件事情:

  1. 它允许我们在函数体内部使用await,继续调用其他异步函数
  2. 它要求其他人调用该函数时,必须使用await关键字

结构化并发

  • 对于同步函数来说,线程决定了它的执行环境。而对于异步函数,线程的概念被弱化,异步函数的执行环境交由任务 (Task) 决定

  • Swift 提供了一系列 Task相关 API 来让开发者创建、组织、检查和取消任务

  • 这些 API 围绕着 Task 这一核心类型,为每一组并发任务构建出一棵结构化的任务树:

    • 一个任务具有它自己的优先级和取消标识,它可以拥有若干个子任务并在其中执行异步函数。
    • 当一个父任务被取消时,这个父任务的取消标识将被设置,并向下传递到所有的子任务中去。
    • 无论是正常完成还是抛出错误,子任务会将结果向上报告给父任务,在所有子任务完成之前 (不论是正常结束还是抛出),父任务是不会完成的。

听上去和Operation很类似,但语法写起来更简洁

既然异步函数的上下文是Task,那第一个Task,或者说第一个任务树环境是怎么来的?

  • 要回答这个问题还需要更深入的学习,但初期的话,可以先从Task这个结构开始了解
  • 简单地使用 Task.init 就可以让我们获取一个任务执行的上下文环境,它接受一个 async 标记的闭包,代码如下所示:
swift 复制代码
        struct Task<Success, Failure> where Failure : Error {
            init(
                priority: TaskPriority? = nil,
                operation: @escaping @Sendable () async throws -> Success
            )
        }
        
        var results: [String] = []
        func someSyncMethod() {
            Task {
                try await processFromScratch()
                print("Done: \(results)")
            }
        }
        func processFromScratch() async throws {
            let strings = try await loadFromDatabase()
            if let signature = try await loadSignature() {
                strings.forEach {
                    results.append($0.appending(signature))
                }
            } else {
                throw NoSignatureError()
            }
        }
  • 在这个Task中执行的闭包,就是一个新任务树的根节点

Actor模型

actor模型是为了保证多线程并发读写共享资源不冲突而存在的,简单理解actor模型的话可以参考如下代码:

swift 复制代码
class Holder {
	private let queue = DispatchQueue(label: "resultholder.queue")
	private var results: [String] = []
	func getResults() -> [String] {
		queue.sync { results }
	}
	
	func setResults(_ results: [String]) {
		queue.sync { self.results = results }
	}
	
	func append(_ value: String) {
		queue.sync { self.results.append(value) }
	}
}
  • 以上的类Holder是在不使用Actor是为了避免共享资源读写冲突而实现的,即通过串行队列对results的读写进行保护

而actor模型的写法则是这样:

swift 复制代码
actor Holder {
	var results: [String] = []
	func setResults(_ results: [String]) {
		self.results = results
	}
	
	func append(_ value: String) {
		results.append(value)
	}
}
  • 只是在class名之前加了一个actor关键词,我们可以简单的认为它就拥有了像上面引入串行队列或者加锁后可以安全读写的效果
  • 有一个戏谑的称呼,原来的写法是手动挡,引入actor后是自动挡的class
相关推荐
游戏开发爱好者825 分钟前
Nginx HTTPS 深入实战 配置、性能与排查全流程(Nginx https
运维·nginx·ios·小程序·https·uni-app·iphone
游戏开发爱好者82 小时前
TCP 抓包分析:tcp抓包工具、 iOS/HTTPS 流量解析全流程
网络协议·tcp/ip·ios·小程序·https·uni-app·iphone
天堂罗恋歌3 小时前
CocoaPods 安装 Masonry 库时出现的网络连接问题处理
ios·iphone·xcode·cocoapods·app store
2501_916008893 小时前
iOS 26 软件性能测试全流程,启动渲染资源压力对比与优化策略
android·macos·ios·小程序·uni-app·cocoa·iphone
00后程序员张4 小时前
iOS 26 兼容测试实战,机型兼容、SwiftUI 兼容性改动
android·ios·小程序·uni-app·swiftui·cocoa·iphone
2501_915106325 小时前
iOS 可分发是已经上架了吗?深入解析应用分发状态、ipa 文件上传、TestFlight 测试与 App Store 审核流程
android·ios·小程序·https·uni-app·iphone·webview
2501_9160074713 小时前
HTTPS 抓包乱码怎么办?原因剖析、排查步骤与实战工具对策(HTTPS 抓包乱码、gzipbrotli、TLS 解密、iOS 抓包)
android·ios·小程序·https·uni-app·iphone·webview
2501_9160088919 小时前
HTTPS 双向认证抓包实战,原理、难点、工具与可操作的排查流程
网络协议·http·ios·小程序·https·uni-app·iphone
2501_9151063219 小时前
HTTPS 能抓包吗?实战答案与逐步可行方案(HTTPS 抓包原理、证书Pinning双向认证应对、工具对比)
网络协议·http·ios·小程序·https·uni-app·iphone
游戏开发爱好者819 小时前
App HTTPS 抓包实战,原理、常见问题与可行工具路线(开发 测试 安全 角度)
网络协议·安全·ios·小程序·https·uni-app·iphone