Skip to content

Mutex & Synchronization — Thread-Safe Primitives ​

Purpose: Low-level synchronization primitives for when actors are too slow or heavyweight Swift Version: Swift 6 for Mutex, Swift 5+ for OSAllocatedUnfairLock iOS Version: iOS 18+ for Mutex, iOS 16+ for OSAllocatedUnfairLock

When to Use ​

✅ Use this skill when:

  • Microsecond operations where actor hop is too slow
  • Protecting single property access
  • Shared state across modules (Mutex is Sendable)
  • High-frequency counters (use Atomic)

❌ Do NOT use this skill for:

  • Complex async workflows (use actors)
  • Need suspension points (use actors)
  • Simple cases where actor is sufficient

When to Use Mutex vs Actor ​

NeedUseReason
Microsecond operationsMutexNo async hop overhead
Protect single propertyMutexSimpler, faster
Complex async workflowsActorProper suspension handling
Suspension points neededActorMutex can't suspend
High-frequency countersAtomicLock-free performance

Key APIs ​

Mutex (iOS 18+ / Swift 6) ​

swift
import Synchronization

let mutex = Mutex<Int>(0)

// Read
let value = mutex.withLock { $0 }

// Write
mutex.withLock { $0 += 1 }

OSAllocatedUnfairLock (iOS 16+) ​

swift
import os

let lock = OSAllocatedUnfairLock(initialState: 0)

lock.withLock { state in
    state += 1
}

Critical Warning: Never Hold Locks Across Await ​

swift
// ❌ DEADLOCK RISK
mutex.withLock {
    await someAsyncWork()  // Task suspends while holding lock!
}

// ✅ SAFE: Release before await
let value = mutex.withLock { $0 }
let result = await process(value)
mutex.withLock { $0 = result }

Resources ​

Released under the MIT License