Atualização editorial em : fontes e exemplos revistos; a data da publicação original foi preservada.

Uma fila com mutex e condition_variable é um exemplo de coordenação entre threads, não evidência de baixa latência. Antes de discutir desempenho, o programa precisa definir o que acontece quando não há itens e como os consumidores terminam.

As regras de sincronização relevantes

As C++ Core Guidelines recomendam esperar por uma condição verificável (CP.42), limitar a duração de seções críticas (CP.43) e não sustentar afirmações de desempenho sem medições (Per.6). No exemplo abaixo, a condição é haver um item ou a fila ter sido fechada. O processamento do item fica fora do bloqueio da fila.

Fila finita no uso, com encerramento explícito

A classe didática aceita inteiros. enviar retorna falso depois do fechamento. receber aguarda quando a fila está vazia e aberta; depois de fechada, entrega os itens restantes e só então retorna std::nullopt. Fechar novamente é permitido. O arquivo fila.hpp contém a implementação completa:

#pragma once
#include <condition_variable>
#include <mutex>
#include <optional>
#include <queue>

class Fila {
    std::mutex mutex_;
    std::condition_variable pronta_;
    std::queue<int> itens_;
    bool fechada_ = false;

public:
    bool enviar(int valor) {
        {
            std::lock_guard<std::mutex> trava(mutex_);
            if (fechada_) return false;
            itens_.push(valor);
        }
        pronta_.notify_one();
        return true;
    }

    std::optional<int> receber() {
        std::unique_lock<std::mutex> trava(mutex_);
        pronta_.wait(trava, [this] { return fechada_ || !itens_.empty(); });
        if (itens_.empty()) return std::nullopt;
        const int valor = itens_.front();
        itens_.pop();
        return valor;
    }

    void fechar() {
        {
            std::lock_guard<std::mutex> trava(mutex_);
            fechada_ = true;
        }
        pronta_.notify_all();
    }
};

O consumidor consulta o estado sob o mesmo mutex que protege a inserção e o fechamento. A notificação não é tratada como um item: ao acordar, a condição é conferida novamente. notify_all no fechamento permite que mais de um consumidor observe o encerramento.

O programa main.cpp envia três valores, fecha a fila e aguarda a thread antes de destruir os objetos compartilhados. A impressão ocorre depois que receber libera sua trava:

#include "fila.hpp"
#include <iostream>
#include <thread>

int main() {
    Fila fila;
    std::thread consumidor([&] {
        while (auto valor = fila.receber()) {
            std::cout << *valor << '\n';
        }
    });
    try {
        for (int valor = 1; valor <= 3; ++valor) fila.enviar(valor);
    } catch (...) {
        fila.fechar();
        consumidor.join();
        throw;
    }
    fila.fechar();
    consumidor.join();
}

Em um ambiente com GCC e suporte a C++17, salve os arquivos no mesmo diretório e compile a partir dele:

g++ -std=c++17 -Wall -Wextra -Werror -pedantic -pthread main.cpp -o fila
./fila
g++ -std=c++17 -Wall -Wextra -Werror -pedantic -pthread test.cpp -o teste
./teste

A saída do programa é 1, 2 e 3, uma linha por valor. O arquivo test.cpp verifica ordem FIFO, drenagem após fechar, rejeição de novos envios, fim de consumidores e entrega de 10.000 inteiros sem perda ou duplicação usando dois consumidores. O job cpp-example compila o programa e repete os testes no CI. Isso verifica comportamento funcional nos cenários executados, não todas as possíveis intercalações de threads.

Por que o exemplo não comprova baixa latência

Não há benchmark de latência ou garantia de tempo real. A fila não limita memória, não oferece cancelamento nem controle de pressão e deve existir até todos os usuários terminarem. Não há promessa de justiça entre consumidores. A referência anterior era uma vaga de emprego sem URL recuperável; ela não sustentava uma experiência pessoal ou resultados de desempenho. A revisão substitui essa narrativa por um exemplo funcional limitado, sem atribuir testes profissionais a Anderson Damasio.