Variáveis de condição e padrões de trabalhadores
Coordene threads com std::condition_variable e o padrão clássico de conjunto de trabalhadores
Variáveis de condição e padrões de trabalhadores é uma aula grátis de C++ Academy no CoddyKit. Esta é a aula 3 de 4. Você pode ler a aula completa abaixo gratuitamente — depois pratica ao vivo no navegador com um editor de código integrado e um tutor de IA 24/7. Faz parte do caminho de aprendizado de C++ Academy, e seu progresso é sincronizado entre a web e o app CoddyKit. O curso de C++ Academy inclui 4 aulas no total.
O que é uma variável de condição?
Uma variável de condição permite que uma linha de execução aguarde até que outra sinalize que uma condição mudou. Ela é usada para coordenar produtores e consumidores.
Noções básicas de std::condition_variable
Uma variável de condição funciona com um std::mutex e um predicado. A linha de execução que aguarda libera o bloqueio enquanto espera e o readquire ao ser despertada.
#include <condition_variable>
#include <mutex>
#include <queue>
std::mutex mtx;
std::condition_variable cv;
std::queue<int> tasks;
bool done = false;Aguardando uma condição
Use cv.wait(lock, predicate). Isso desbloqueia atomicamente o mutex e coloca a linha de execução para dormir até que ela seja notificada. Ao despertar, ela bloqueia o mutex novamente e verifica o predicado; se ele for falso, volta a dormir.
std::unique_lock<std::mutex> lock(mtx);
cv.wait(lock, [] { return !tasks.empty() || done; });Notificação
O encadeamento produtor chama cv.notify_one() ou cv.notify_all() depois de alterar o estado. O bloqueio deve ser mantido durante a alteração do estado.
{
std::lock_guard<std::mutex> lock(mtx);
tasks.push(42);
}
cv.notify_one();Padrão Produtor-Consumidor
Exemplo clássico: os produtores inserem tarefas; os consumidores aguardam tarefas.
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);
}
}Despertares Espúrios
Um encadeamento que aguarda uma variável de condição pode ser despertado sem uma notificação. Por isso, wait recebe um predicado — ele verifica novamente a condição a cada despertar.
notify_one versus notify_all
Use notify_one quando um encadeamento em espera puder avançar. Use notify_all quando as alterações de estado afetarem todos os encadeamentos em espera (por exemplo, um sinal de encerramento).
Esperas Temporizadas
wait_for(lock, duration) e wait_until(lock, time_point) despertam após uma notificação ou depois de um tempo limite.
if (cv.wait_for(lock, 1s, [] { return ready; })) {
/* condition met */
} else {
/* timed out */
}Esqueleto de um Pool de Trabalhadores
Um padrão comum: um conjunto fixo de encadeamentos trabalhadores retira itens de uma fila compartilhada. Crie-o com mutex + variável de condição + fila + sinalizador atômico de parada.
Evitando Despertares Perdidos
Sempre modifique o estado compartilhado e chame notify_* mantendo o mutex durante a alteração do estado (liberá-lo imediatamente antes da notificação também é aceitável, mas garanta a ordenação). Caso contrário, um encadeamento em espera poderá perder a notificação.
std::counting_semaphore (C++20)
Para sinalização simples baseada em contagem, o C++20 adicionou std::counting_semaphore — mais simples que as variáveis de condição para alguns padrões.
Cuidado com Impasses
Manter vários bloqueios enquanto se aguarda uma variável de condição pode causar um impasse. Adquira os bloqueios em uma ordem consistente e use std::scoped_lock para vários mutexes.
Verificação Rápida
Por que cv.wait(lock, predicate) recebe um predicado mesmo quando você deseja apenas aguardar uma notificação?
Recapitulação
Uma variável de condição coordena encadeamentos que aguardam uma alteração de estado. Use wait(lock, predicate) para lidar com despertares espúrios, modifique o estado sob o mutex e depois chame notify_one ou notify_all.
Perguntas Frequentes
A aula “Variáveis de condição e padrões de trabalhadores” é grátis?
Sim — o texto completo de “Variáveis de condição e padrões de trabalhadores” é grátis para ler aqui na web. Para praticá-la interativamente (um editor de código integrado e um tutor de IA 24/7) e desbloquear o restante do curso de C++ Academy, atualize para CoddyKit PRO. O curso de C++ Academy inclui 4 aulas no total.
O que vou aprender em “Variáveis de condição e padrões de trabalhadores”?
Coordene threads com std::condition_variable e o padrão clássico de conjunto de trabalhadores Você pratica C++ Academy com código prático que executa diretamente no navegador, e um tutor de IA 24/7 responde suas dúvidas enquanto trabalha na aula.
Preciso ter experiência prévia para começar C++ Academy?
Nenhuma experiência prévia é necessária. C++ Academy no CoddyKit é estruturado para alunos iniciantes até avançados, então você pode começar aqui ou desde o início e aprender no seu ritmo. Esta é a aula 3 de 4.
Quanto tempo leva a aula “Variáveis de condição e padrões de trabalhadores”?
A maioria das aulas CoddyKit leva cerca de 5–10 minutos. Cada uma é compacta e interativa, então você faz progresso constante e retoma exatamente de onde parou entre web e app.
Posso escrever e executar código nesta aula de C++ Academy?
Sim. Cada aula de C++ Academy inclui um editor de código integrado, então você escreve e executa código real direto no navegador e recebe feedback de IA instantaneamente — nenhuma configuração local necessária.
Todas as aulas deste curso
- std::thread: juntar e separar
- std::mutex, lock_guard e unique_lock
- Variáveis de condição e padrões de trabalhadores
- Noções básicas de std::async e std::future