← Назад к вопросам

Как реализован Semaphore?

2.0 Middle🔥 121 комментариев
#Многопоточность и асинхронность

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI26 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Realizacija Semaphore v iOS

Semaphore - eto primitiv sinkhronizacii dlja upravlenija dostupom k ogranichennomu resursu. Chasto ispol'zuju ego dlja kontrolja parallel'nykh operacij.

Osnovnaja ideja

Semaphore podderzhivaet schetchik:

  • signal() - uvelichivaet schetchik (osvobazhda et resurs)
  • wait() - umenshaet schetchik (zajima et resurs)
  • Esli schetchik = 0, potok blokiruetsja do signal()

Ispol'zovanie v iOS

Dispatch Semaphore realizovan v Darwin kernel:

import Dispatch

let semaphore = DispatchSemaphore(value: 3)
if semaphore.wait(timeout: .now() + 10) == .timedOut {
    print("Timeout!")
}
semaphore.signal()

Ogranichenie parallel'nykh operacij

Osnovnoe primenenie - kontrol' odnovremennyh zadach:

func downloadImages(urls: [URL]) async {
    let semaphore = DispatchSemaphore(value: 3)
    let queue = DispatchQueue.global()
    
    for url in urls {
        queue.async {
            semaphore.wait()
            defer { semaphore.signal() }
            let _ = try? Data(contentsOf: url)
            print("Downloaded")
        }
    }
}

Sinkhronizacija async/await

Semaphore polezen dlja sinkhronizacii async operacij:

func fetchDataSequentially() async {
    let semaphore = DispatchSemaphore(value: 1)
    
    let task1 = Task {
        semaphore.wait()
        defer { semaphore.signal() }
        let data = try await fetchUserData()
    }
    
    await task1.value
}

Vnutrennjaja realizacija

Vnutri Darwin kernel ispol'zujutsja:

  • Atomic operacii dlja izmenenija schetchika
  • Futex dlja jeffektivnoj blokirovki potokov
  • Ochered' zhidajushhikh potokov dlja spravedlivogo raspredelenija

Prakticheskie primenenija

1. Ogranichenie setevykh zaprosov:

class APIClient {
    private let semaphore = DispatchSemaphore(value: 5)
    
    func request<T: Decodable>(_ endpoint: String) async throws -> T {
        semaphore.wait()
        defer { semaphore.signal() }
        let url = URL(string: endpoint)!
        let (data, _) = try await URLSession.shared.data(from: url)
        return try JSONDecoder().decode(T.self, from: data)
    }
}

2. Ochered' obrabotki zadach:

class TaskProcessor {
    private let semaphore = DispatchSemaphore(value: 1)
    
    func processTask(_ task: Task) {
        semaphore.wait()
        defer { semaphore.signal() }
        task.execute()
    }
}

Vazhnye osobennosti

  • Ne mozhet byt' otricatel'nym - schetchik nizhe nulja nevozmozhен
  • FIFO ochered - potoki prosjpaetsja v porjadke ocheredi
  • Deadlock risk - nuzhna akkunatnost' s zavisimosjami
  • Timeout podderzhka - mozhno ustanovit' maksimal'noe vremja

Semaphore - eto moshhnыj instrument dlja upravlenija parallelizmom.

Как реализован Semaphore? | PrepBro