← Назад к вопросам
Как реализован 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.