本文档概述了 Swift 的并发模型,该模型通过 async/await、Actor 和结构化任务实现安全高效的并行执行。它涵盖了核心组件、它们的交互以及 Swift 编译器强制执行的安全机制。
有关分布式 Actor 的信息,请参阅 分布式 Actor。
Swift 的并发模型建立在三个关键组件之上
来源
stdlib/public/Concurrency/Task.swift14-92: void }
class TaskPriority { +high: TaskPriority +medium: TaskPriority +low: TaskPriority +userInitiated: TaskPriority +utility: TaskPriority +background: TaskPriority }
Task -- TaskPriority
Tasks can be:
- **Structured**: Child tasks with a parent-child relationship, automatically managed as part of a scope
- **Unstructured**: Top-level tasks created with `Task { ... }` that exist independently
- **Detached**: Tasks that don't inherit the parent's priority or context
Sources:
- <FileRef file-url="https://github.com/swiftlang/swift/blob/721944a9/stdlib/public/Concurrency/Task.swift#L142-L151" min=142 max=151 file-path="stdlib/public/Concurrency/Task.swift">Hii</FileRef>"| ActorA
Task2 -->|"await (suspended)<br>(waiting for access)"| ActorA
Task3 -->|"await (suspended)<br>(waiting for access)"| ActorA
ActorMailbox["Actor Mailbox<br>Message Queue"]
ActorA --- ActorMailbox
ActorMailbox --- Task2
ActorMailbox --- Task3
end
主要特性
@MainActor 这样的全局 Actor 提供全局隔离域来源
// 非结构化任务 let task = Task { return await performComputation() } let result = await task.value
// 分离任务 let task = Task.detached { return await performBackgroundWork() }
When a task is created, it is scheduled on an executor and will run when resources are available.
Sources:
- <FileRef file-url="https://github.com/swiftlang/swift/blob/721944a9/stdlib/public/Concurrency/Task.swift#L597-L644" min=597 max=644 file-path="stdlib/public/Concurrency/Task.swift">Hii</FileRef>"]
Medium["medium<br>(0x15)"]
Low["low / utility<br>(0x11)"]
Background["background<br>(0x09)"]
High --> Medium
Medium --> Low
Low --> Background
end
子任务默认继承父任务的优先级。系统内置了优先级反转保护,以防止低优先级任务阻塞高优先级任务。
来源
next(): 检索下一个已完成的结果cancelAll(): 取消所有子任务来源
Cancellation propagates to child tasks automatically. Tasks can:
- Check for cancellation with `Task.checkCancellation()`
- Register cancellation handlers with `withTaskCancellationHandler()`
- Respond to cancellation by returning early, throwing, or cleaning up resources
Sources:
- <FileRef file-url="https://github.com/swiftlang/swift/blob/721944a9/stdlib/public/Concurrency/Task.swift#L197-L237" min=197 max=237 file-path="stdlib/public/Concurrency/Task.swift">Hii</FileRef>"| ChildTask1
ChildTask2 -->|"withTaskLocal { x = 2 }"| ChildTask2
GrandChildTask -->|"x = 1 (inherited from parent)"| GrandChildTask
任务本地值
@TaskLocal 属性定义withTaskLocal() 在特定作用域内绑定来源
stdlib/public/Concurrency/TaskLocal.swift32-52"] NonIsolated["非隔离域
(异步访问)"]
ActorDef -->|"defines isolation domain"| Isolated
NonIsolated -->|"await"| Isolated
IsolatedProp["actor var property"]
IsolatedMethod["func method()"]
NonIsolatedMethod["nonisolated func method()"]
ActorDef --- IsolatedProp
ActorDef --- IsolatedMethod
ActorDef --- NonIsolatedMethod
IsolatedProp --- Isolated
IsolatedMethod --- Isolated
NonIsolatedMethod --- NonIsolated
end
Actor isolation rules:
- Actor properties can only be accessed directly from within the actor
- Actor methods are implicitly isolated to the actor
- Methods marked with `nonisolated` can be called synchronously from outside
- Calling an actor method from outside requires `await`
- Access to actor state from outside is implicitly asynchronous
Sources:
- <FileRef file-url="https://github.com/swiftlang/swift/blob/721944a9/test/Concurrency/actor_isolation.swift#L36-L87" min=36 max=87 file-path="test/Concurrency/actor_isolation.swift">Hii</FileRef>"]
MainActorProp["@MainActor var property"]
CustomActorCode["@CustomGlobalActor func customFunc()"]
MainActor --- MainActorCode
MainActor --- MainActorProp
GlobalActorDef --- CustomActorCode
end
常见的全局 Actor
@MainActor: 确保代码在主线程/队列上运行@globalActor 定义的自定义全局 Actor全局 Actor 可以应用于
来源
Reentrancy considerations:
- Can cause subtle bugs if actor state is inconsistent between entries
- Actor isolation still ensures only one task runs actor code at a time
- Careful consideration needed for methods that modify state before awaiting
Sources:
- <FileRef file-url="https://github.com/swiftlang/swift/blob/721944a9/stdlib/public/Concurrency/Actor.cpp#L96-L134" min=96 max=134 file-path="stdlib/public/Concurrency/Actor.cpp">Hii</FileRef>"]
SendableClasses["@Sendable Classes"]
FinalClasses["Final Classes with Sendable Properties"]
UncheckedSendable["@unchecked Sendable Types"]
SendableProtocol --- ValueTypes
SendableProtocol --- SendableClasses
SendableProtocol --- FinalClasses
SendableProtocol --- UncheckedSendable
CrossActor["Cross-Actor References"]
SendableProtocol -->|"required for"| CrossActor
end
Sendable 检查
@Sendable@unchecked Sendable来源
lib/Sema/TypeCheckConcurrency.cpp879-955"] DifferentActor["不同 Actor
(需要 Await)"] NonIsolated["非隔离上下文
(需要 Await)"]
IsolationCheck -->|"allowed"| SameActor
IsolationCheck -->|"enforced"| DifferentActor
IsolationCheck -->|"enforced"| NonIsolated
SyncAccess["Synchronous Access Attempt"]
AsyncAccess["Asynchronous Access"]
DifferentActor --- SyncAccess
NonIsolated --- SyncAccess
DifferentActor --- AsyncAccess
NonIsolated --- AsyncAccess
SyncAccess -->|"compile error"| Error["Error: actor-isolated property cannot be referenced"]
AsyncAccess -->|"allowed"| Valid["Valid: await actor.property"]
end
The compiler checks:
- Access to actor properties and methods
- Crossing actor boundaries with proper `await`
- Preventing data races by enforcing isolation
Sources:
- <FileRef file-url="https://github.com/swiftlang/swift/blob/721944a9/lib/Sema/TypeCheckConcurrency.cpp#L235-L269" min=235 max=269 file-path="lib/Sema/TypeCheckConcurrency.cpp">Hii</FileRef>"]
Add["group.addTask { ... }"]
Next["await group.next()"]
Cancel["group.cancelAll()"]
Loop["for await result in group { ... }"]
Group -->|"1. create group"| Add
Add -->|"2. add tasks"| Add
Add -->|"3. collect results"| Next
Next -->|"continue collecting"| Next
Next -->|"or"| Loop
Next -->|"4. optionally"| Cancel
Loop -->|"5. group scope exits"| Complete["All tasks complete"]
end
任务组有两种变体
withTaskGroup: 用于非抛出子任务withThrowingTaskGroup: 用于可能抛出错误的子任务来源
stdlib/public/Concurrency/TaskGroup.swift65-125 Add["group.addTask { ... }"] Cancel["group.cancelAll()"]
Group -->|"create group"| Add
Add -->|"add more tasks"| Add
Add -->|"optionally"| Cancel
Group -->|"group scope exits<br>results discarded"| Complete["All tasks complete<br>(results ignored)"]
end
Discarding task groups are useful when:
- Task side effects are more important than return values
- You need to limit memory usage by not accumulating results
- The only relevant outcome is whether tasks completed or failed
Sources:
- <FileRef file-url="https://github.com/swiftlang/swift/blob/721944a9/stdlib/public/Concurrency/DiscardingTaskGroup.swift#L15-L25" min=15 max=25 file-path="stdlib/public/Concurrency/DiscardingTaskGroup.swift">Hii</FileRef>"]
Reading["let id = contextID"]
ChildTask["Task { ... contextID ... }"]
Declaration -->|"define"| Binding
Binding -->|"set value in scope"| Reading
Binding -->|"inherits value"| ChildTask
end
任务本地值用于
来源
stdlib/public/Concurrency/TaskLocal.swift32-52"] OtherWork["执行其他工作"] AwaitResult["await 结果"]
AsyncLet -->|"starts task"| OtherWork
OtherWork -->|"when value needed"| AwaitResult
end
Key characteristics:
- Creates a child task that executes concurrently
- Results are awaited when accessed
- Automatically managed as part of structured concurrency
- Errors propagate to the parent task
Sources:
- <FileRef file-url="https://github.com/swiftlang/swift/blob/721944a9/stdlib/public/Concurrency/AsyncLet.cpp#L1-L16" min=1 max=16 file-path="stdlib/public/Concurrency/AsyncLet.cpp">Hii</FileRef>"]
API -->|"uses"| Runtime
Runtime -->|"implements"| Executor
Runtime -->|"implements"| Scheduling
Executor -->|"leverages"| PlatformIntegration
Scheduling -->|"leverages"| PlatformIntegration
end
运行时处理
来源
Swift 的并发模型提供了一种全面的、类型安全的并发编程方法。通过将任务、Actor 和 async/await 与编译时强制执行的隔离和 Sendable 机制相结合,Swift 使编写正确的并发代码更加容易。该系统内置的结构化并发、任务管理和 Actor 隔离功能有助于防止常见并发错误,如数据竞争、死锁和优先级反转。
并发系统与 Swift 的类型系统深度集成,尽可能提供在编译时检查的安全保证。与使用线程和锁的传统方法相比,这使得并发代码更加可靠且易于理解。