Skip to content

groue/Semaphore

Repository files navigation

Semaphore

A Synchronization Primitive for Swift Concurrency

Requirements: iOS 13.0+ / macOS 10.15+ / tvOS 13.0+ / watchOS 6.0+ • Swift 5.10+ / Xcode 15.3+

📖 Documentation


This package provides AsyncSemaphore, a traditional counting semaphore.

Unlike DispatchSemaphore, it does not block any thread. Instead, Swift concurrency tasks are suspended "awaiting" for the semaphore.

Usage

You can use a semaphore to suspend a task and resume it later:

let semaphore = AsyncSemaphore(value: 0) Task { // Suspends the task until a signal occurs. await semaphore.wait() await doSomething() } // Resumes the suspended task. semaphore.signal()

An actor can use a semaphore so that its methods can't run concurrently, avoiding the "actor reentrancy problem":

actor MyActor { private let semaphore = AsyncSemaphore(value: 1) func serializedMethod() async { // Makes sure no two tasks can execute // serializedMethod() concurrently. await semaphore.wait() defer { semaphore.signal() } await doSomething() await doSomethingElse() } }

A semaphore can generally limit the number of concurrent accesses to a resource:

class Downloader { private let semaphore: AsyncSemaphore /// Creates a Downloader that can run at most /// `maxDownloadCount` concurrent downloads. init(maxDownloadCount: Int) { semaphore = AsyncSemaphore(value: maxDownloadCount) } func download(...) async throws -> Data { try await semaphore.waitUnlessCancelled() defer { semaphore.signal() } return try await ... } }

You can see in the latest example that the wait() method has a waitUnlessCancelled variant that throws CancellationError if the task is cancelled before a signal occurs.

For a nice introduction to semaphores, see The Beauty of Semaphores in Swift 🚦. The article discusses DispatchSemaphore, but it can easily be ported to Swift concurrency: get inspiration from the above examples.

About

A Synchronization Primitive for Swift Concurrency

Topics

Resources

License

Stars

Watchers

Forks

Sponsor this project

 

Packages

No packages published

Contributors 3

  •  
  •  
  •  

Languages