10.11 · Groups, semaphores, parallel loops, operation dependencies, QoS and timers
The queue APIs still carry a lot of production code. These questions are the details that cause real bugs: unbalanced groups, throttling, cancelled dependencies and what inherits which QoS.
Mental model. GCD has no compiler help: balance every enter, every wait and every resume yourself.
Coordination and loops
Group and semaphore misuse, concurrentPerform, timers.
- What goes wrong with an unbalanced DispatchGroup, and how do you use a semaphore to throttle work without deadlocking?
A DispatchGroup is a counter: enter() adds one, leave() removes one, and wait() or notify fires at zero. The two bugs are forgetting a leave (the group never… - What does DispatchQueue.concurrentPerform do, when is it better than a loop of async calls, and how do you use it safely?
concurrentPerform(iterations:) runs the closure for each index in parallel, using only as many threads as there are cores, and blocks the caller until every… - How does a DispatchSourceTimer differ from Timer, and what are the lifecycle rules that crash if you break them?
A dispatch timer source fires its handler on a queue you choose, independent of any run loop, so it works on background queues and is not paused when the main…
Operations and QoS
Dependencies and cancellation, and how QoS propagates.
- How do Operation dependencies, cancellation and states interact, and what happens to a dependent operation when its dependency is cancelled?
Dependencies are a directed graph of prerequisites: an operation becomes ready only when all its dependencies have finished, regardless of the order you add… - How does quality of service propagate between queues and blocks, and why does it matter for priority inversion?
Every block has a QoS (userInteractive, userInitiated, utility, background, default). A block submitted with async from another block inherits the submitter’s…
More in Concurrency
- 10.1 · Queues, QoS, barriers, groups, semaphores and sources
- 10.2 · Operation, OperationQueue, dependencies and cancellation
- 10.3 · async/await, tasks, task groups, cancellation and task locals
- 10.4 · Actors, reentrancy, isolated, nonisolated, global actors and @MainActor
- 10.5 · Region-based isolation, sending, and migrating to Swift 6
- 10.6 · Continuations and bridging GCD, Combine and callback APIs
- 10.7 · Deadlocks, main-actor hops, Thread Sanitizer and Instruments
- 10.8 · Task groups, async let, cancellation and task locals in practice
- 10.9 · Isolation rules, isolated parameters, global actors, main-actor hops and default isolation
- 10.10 · Sendable rules, locks versus actors, and the escape hatches
- 10.12 · AsyncStream buffering, continuation misuse and notifications as async sequences