Filas de Tarefas para C++: do Simples ao Complexo
Uma fila de tarefas (Task Queue) é um dos padrões-chave da programação multithread. Ela permite organizar a execução assíncrona de trabalho: um ou mais threads produtores adicionam tarefas, e um pool de threads trabalhadores as processa. Em C++, existem tanto meios padrão quanto bibliotecas especializadas para isso.
1. Fila Padrão: std::queue com Locks
A opção mais simples é usar std::queue em conjunto com um mutex e uma variável de condição. Isso é adequado para projetos pequenos, onde a sobrecarga de sincronização não é crítica.
#include <queue>#include <mutex>#include <condition_variable>
template<typename T>class ThreadSafeQueue { std::queue<T> q_; mutable std::mutex mtx_; std::condition_variable cv_;public: void push(T value) { std::lock_guard<std::mutex> lock(mtx_); q_.push(std::move(value)); cv_.notify_one(); }
T pop() { std::unique_lock<std::mutex> lock(mtx_); cv_.wait(lock, [this]{ return !q_.empty(); }); T val = std::move(q_.front()); q_.pop(); return val; }};Prós: simplicidade, embutido na biblioteca padrão.
Contras: locks em cada operação, possíveis contenção e inversão de prioridades.
2. boost::lockfree::queue — Fila Lock-Free
A biblioteca Boost fornece estruturas de dados lock-free baseadas em operações CAS. boost::lockfree::queue é uma fila multithread sem locks, usando um pool de memória fixo ou dinâmico.
#include <boost/lockfree/queue.hpp>
boost::lockfree::queue<int> queue(128); // tamanho fixo
void producer() { for (int i = 0; i < 1000; ++i) { while (!queue.push(i)) { // se a fila estiver cheia, espera ou descarta } }}
void consumer() { int value; while (queue.pop(value)) { process(value); }}Prós: alta performance com filas pequenas, ausência de locks.
Contras: complexidade de depuração, tamanho limitado (para versão fixa), necessidade de memory reclamation.
3. Intel TBB (Threading Building Blocks) — tbb::concurrent_queue
Intel TBB é uma biblioteca industrial para programação paralela. Sua tbb::concurrent_queue (e tbb::concurrent_bounded_queue) são otimizadas para alta carga.
#include <tbb/concurrent_queue.h>
tbb::concurrent_bounded_queue<Task> task_queue;task_queue.set_capacity(1024); // limita o tamanho
// Produtortask_queue.push(std::move(task));
// ConsumidorTask t;if (task_queue.try_pop(t)) { t.execute();}Prós: excelente escalabilidade, suporte a modos bounded/unbounded, integração com o TBB task scheduler.
Contras: licença Apache 2.0 (anteriormente GPL), dependência de toda a biblioteca TBB.
4. libdispatch (Grand Central Dispatch) via C++ binding
GCD é um sistema de gerenciamento de filas da Apple, disponível em macOS/iOS. Para C++, existe o wrapper dispatch/queue. No Linux, pode-se usar libdispatch (opensource).
#include <dispatch/dispatch.h>
dispatch_queue_t queue = dispatch_queue_create("com.example.myqueue", DISPATCH_QUEUE_CONCURRENT);
dispatch_async(queue, ^{ // tarefa 1});
dispatch_async(queue, ^{ // tarefa 2});
dispatch_release(queue);Prós: gerenciamento eficiente de threads, escalonamento automático para o número de núcleos.
Contras: limitado
Também na biblioteca
Envio de SMS em TypeScript: Bibliotecas de API e Integração
Spring Data JPA para Java: guia completo com exemplos
Planejador de tarefas em Rust: criando um job scheduler confiável
Trabalho com imagens em PHP: redimensionamento, corte e otimização com GD e Imagick