Что такое критическая секция в многопоточном программировании?

«Что такое критическая секция в многопоточном программировании?» — вопрос из категории Многопоточность, который задают на 10% собеседований IOS Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Критическая секция — это участок кода, в котором происходит обращение к общему ресурсу (переменной, структуре данных, файлу), доступному нескольким потокам или задачам одновременно. Без синхронизации это приводит к состоянию гонки (race condition), когда результат выполнения зависит от неуправляемого порядка операций между потоками.

Цель — обеспечить эксклюзивный доступ к ресурсу для одного потока в данный момент времени, используя механизмы синхронизации.

Примеры синхронизации в iOS/macOS:

  • NSLock / os_unfair_lock: Базовые примитивы для явной блокировки.
  • DispatchQueue с барьером (flags: .barrier): Для безопасной записи в concurrent очередь.
  • Акторы (Actor) в Swift: Модель, обеспечивающая изоляцию состояния по умолчанию.
  • Семафоры (DispatchSemaphore): Для контроля доступа к ограниченному числу ресурсов.

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

let serialQueue = DispatchQueue(label: "com.example.serial")
var sharedCounter = 0

func incrementCounter() {
    serialQueue.async {
        // Критическая секция защищена очередью
        sharedCounter += 1
        print(sharedCounter)
    }
}
// Все обращения к `sharedCounter` будут последовательными.

Правило: Код внутри критической секции должен выполняться максимально быстро, чтобы минимизировать блокировку других потоков.