Middle
Cos'è un semaforo nel contesto della programmazione?
sobes.tech AI
Risposta dell'AI
Il semaforo è una primitive di sincronizzazione dei thread che controlla l'accesso a una risorsa limitata. Tiene traccia di un contatore intero.
Operazioni principali:
wait()(oP/acquire) : Diminuisce il contatore di 1. Se il contatore diventa negativo, il thread viene bloccato fino a quando un altro eseguesignal().signal()(oV/release) : Aumenta il contatore di 1. Se ci sono thread bloccati, uno di essi viene sbloccato.
Tipi di semafori:
- Semaforo binario (mutex) : Il contatore assume valori 0 o 1. Usato per garantire l'esclusione mutua: solo un thread può accedere alla risorsa alla volta.
- Semaforo contatore : Il contatore può assumere valori da 0 a N. Usato per gestire l'accesso a un pool di risorse con un numero limitato di elementi disponibili.
Esempio di utilizzo in Swift per limitare il numero di task che possono essere eseguiti contemporaneamente:
// Creazione di un semaforo che permette fino a 3 accessi simultanei
let semaphore = DispatchSemaphore(value: 3)
DispatchQueue.global().async {
// Task 1
semaphore.wait() // Diminuisce il contatore, blocca se > 3 task sono in esecuzione
print("Task 1 avviato")
Thread.sleep(forTimeInterval: 2) // Simulazione di lavoro
print("Task 1 completato")
semaphore.signal() // Aumenta il contatore, sblocca le task in attesa
}
DispatchQueue.global().async {
// Task 2
semaphore.wait()
print("Task 2 avviato")
Thread.sleep(forTimeInterval: 3)
print("Task 2 completato")
semaphore.signal()
}
DispatchQueue.global().async {
// Task 3
semaphore.wait()
print("Task 3 avviato")
Thread.sleep(forTimeInterval: 1)
print("Task 3 completato")
semaphore.signal()
}
DispatchQueue.global().async {
// Task 4 (attenderà finché non si libera uno slot)
semaphore.wait()
print("Task 4 avviato")
Thread.sleep(forTimeInterval: 2)
print("Task 4 completato")
semaphore.signal()
}
// Attendere il completamento di tutte le task per la dimostrazione
// Usare meccanismi di attesa più affidabili nel codice reale
Thread.sleep(forTimeInterval: 5)