Variabili di condizione e pattern worker
Coordini i thread con std::condition_variable e il classico pattern del worker pool
Variabili di condizione e pattern worker è una lezione C++ Academy gratuita su CoddyKit. Questa è la lezione 3 di 4. Puoi leggere la lezione completa qui gratuitamente — poi esercitati direttamente nel browser con un editor di codice integrato e un tutor IA disponibile 24/7. Fa parte del percorso di apprendimento C++ Academy, e i tuoi progressi si sincronizzano tra il web e l'app CoddyKit. Il corso C++ Academy include 4 lezioni in totale.
Che cos'è una variabile di condizione?
Una variabile di condizione consente a un thread di attendere finché un altro thread non segnala che una condizione è cambiata. Viene utilizzata per coordinare produttori e consumatori.
Nozioni di base su std::condition_variable
Una variabile di condizione funziona con un std::mutex e un predicato. Il thread in attesa rilascia il lock durante l'attesa e lo acquisisce nuovamente al risveglio.
#include <condition_variable>
#include <mutex>
#include <queue>
std::mutex mtx;
std::condition_variable cv;
std::queue<int> tasks;
bool done = false;Attesa di una condizione
Utilizzi cv.wait(lock, predicate). Sblocca atomicamente il mutex e sospende l'esecuzione finché non riceve una notifica. Al risveglio, acquisisce nuovamente il lock e verifica il predicato; se è falso, torna ad attendere.
std::unique_lock<std::mutex> lock(mtx);
cv.wait(lock, [] { return !tasks.empty() || done; });Notifica
Il thread produttore chiama cv.notify_one() o cv.notify_all() dopo aver modificato lo stato. Il lock dovrebbe essere mantenuto durante la modifica dello stato.
{
std::lock_guard<std::mutex> lock(mtx);
tasks.push(42);
}
cv.notify_one();Schema Produttore-Consumatore
Esempio classico: i produttori inseriscono task; i consumer attendono i task.
void consumer() {
while (true) {
std::unique_lock<std::mutex> lock(mtx);
cv.wait(lock, [] { return !tasks.empty() || done; });
if (done && tasks.empty()) break;
int task = tasks.front();
tasks.pop();
lock.unlock();
process(task);
}
}Risvegli spurii
Un thread in attesa su una variabile di condizione può risvegliarsi senza una notifica. Per questo wait accetta un predicato: lo ricontrolla a ogni risveglio.
notify_one vs notify_all
Utilizzi notify_one quando un solo thread in attesa può procedere. Utilizzi notify_all quando le modifiche allo stato riguardano tutti i thread in attesa, ad esempio per un segnale di arresto.
Attese temporizzate
wait_for(lock, duration) e wait_until(lock, time_point) risvegliano il thread in seguito a una notifica oppure allo scadere del timeout.
if (cv.wait_for(lock, 1s, [] { return ready; })) {
/* condition met */
} else {
/* timed out */
}Struttura di un pool di worker
Un modello comune consiste in un insieme fisso di thread worker che prelevano elementi da una coda condivisa. Lo si costruisce con mutex + condition_variable + queue + atomic stop flag.
Evitare i risvegli persi
Modifichi sempre lo stato condiviso e chiami notify_* mantenendo il mutex acquisito durante la modifica dello stato. Rilasciarlo subito prima della notifica va bene, purché l'ordine sia garantito. In caso contrario, un thread in attesa potrebbe non ricevere la notifica.
std::counting_semaphore (C++20)
Per una segnalazione basata semplicemente su un conteggio, C++20 ha introdotto std::counting_semaphore, più semplice delle variabili di condizione per alcuni modelli.
Attenzione al deadlock
Mantenere più lock mentre si attende su una variabile di condizione può causare un deadlock. Acquisisca i lock in un ordine coerente e utilizzi std::scoped_lock per più mutex.
Verifica rapida
Perché cv.wait(lock, predicate) accetta un predicato anche quando si desidera soltanto attendere una notifica?
Riepilogo
Una variabile di condizione coordina i thread in attesa di una modifica dello stato. Utilizzi wait(lock, predicate) per gestire i risvegli spurii, modifichi lo stato sotto il mutex e poi chiami notify_one o notify_all.
Domande Frequenti
La lezione «Variabili di condizione e pattern worker» è gratuita?
Sì — il testo completo di «Variabili di condizione e pattern worker» è gratuito qui sul web. Per esercitarvi in modo interattivo (un editor di codice integrato e un tutor IA 24/7) e sbloccare il resto del corso C++ Academy, passa a CoddyKit PRO. Il corso C++ Academy include 4 lezioni in totale.
Cosa imparerò in «Variabili di condizione e pattern worker»?
Coordini i thread con std::condition_variable e il classico pattern del worker pool Eserciti C++ Academy con codice pratico che esegui direttamente nel browser, e un tutor IA 24/7 risponde alle tue domande mentre lavori sulla lezione.
Ho bisogno di esperienza per iniziare C++ Academy?
Non è richiesta alcuna esperienza precedente. C++ Academy su CoddyKit è strutturato per principianti e studenti avanzati, quindi puoi iniziare da qui o dall'inizio e procedere al tuo ritmo. Questa è la lezione 3 di 4.
Quanto tempo richiede la lezione «Variabili di condizione e pattern worker»?
La maggior parte delle lezioni CoddyKit richiede circa 5–10 minuti. Ogni lezione è breve e interattiva, quindi fai progressi costanti e riprendi esattamente da dove hai lasciato su web e app.
Posso scrivere ed eseguire codice in questa lezione C++ Academy?
Sì. Ogni lezione C++ Academy include un editor di codice integrato, quindi scrivi ed esegui codice reale direttamente nel tuo browser e ricevi feedback istantaneo dall'IA — nessuna configurazione locale necessaria.
Tutte le lezioni di questo corso
- std::thread: join e detach
- std::mutex, lock_guard e unique_lock
- Variabili di condizione e pattern worker
- Basi di std::async e std::future