Добавить объявление

Современные механизмы блокировок в Swift: Mutex и Synchronization Framework

В Swift существует несколько способов защиты данных от гонки (data races): NSLock, DispatchSemaphore, последовательные очереди (DispatchQueue). Но на WWDC24 компания Apple представила новый Synchronization Framework, включающий современный Mutex - стандартизированную блокировку взаимного исключения.

В чем разница между Lock и Mutex:


  • Lock: общее название механизмов синхронизации (например, NSLock, os_unfair_lock).

  • Mutex: частный случай блокировки, гарантирующий, что только один поток может владеть ресурсом в данный момент.

Ключевая особенность Mutex:


  • Строгое владение - разблокировать может только тот поток, который заблокировал.

  • Поддержка Sendable, что делает его удобным для Swift Concurrency.

Пример использования:


Пример защиты счетчика:

final class Counter {
private let count = Mutex<Int>(0) // Обернули значение в Mutex

var currentCount: Int {
count.withLock { $0 } // Безопасное чтение
}

func increment() {
count.withLock { $0 += 1 } // Атомарная операция
}

func decrement() throws {
try count.withLock {
guard $0 > 0 else { throw Error.reachedZero }
$0 -= 1
}
}
}

Mutex vs Actor:


  • Actor: идеален для асинхронного доступа, но требует await.

  • Mutex: синхронный, подходит для legacy кода или когда нельзя использовать async/await.

Когда выбирать Mutex:


  • Нужна мгновенная синхронная блокировка.

  • Работа с не Sendable типами (например NSBezierPath).

  • Интеграция с кодом, не поддерживающим Concurrency.

Важно:


  • Доступен с iOS 18 и macOS 15.

  • Не заменяет Actor, а дополняет инструментарий для работы с многопоточностью.


Mutex из Synchronization Framework - это современный, безопасный и эффективный способ защиты данных в Swift.
28.07.2025 20 408