Colas de tareas para C++: implementación y uso

Entrenador de Python en Línea para Principiantes

Aprende Python fácilmente sin sobrecargarte de teoría. Resuelve tareas prácticas con verificación automática, recibe pistas y escribe código directamente en el navegador, sin instalar nada.

Start Course

Colas de tareas para C++: de la teoría a la práctica



La cola de tareas (task queue) es uno de los patrones clave de la programación multihilo en C++. Permite distribuir eficientemente el trabajo entre hilos, evitando condiciones de carrera y consumo excesivo de recursos. En este artículo, analizaremos cómo crear y usar colas de tareas en C++ con énfasis en el rendimiento y la seguridad.



¿Para qué sirve una cola de tareas?

En las aplicaciones modernas, a menudo surge la necesidad de ejecutar múltiples tareas pequeñas en paralelo. La creación directa de hilos para cada tarea genera sobrecarga: crear un hilo consume tiempo y memoria. La cola de tareas resuelve este problema mediante un pool de hilos (thread pool):

  • Reutilización de hilos — los hilos no se destruyen tras ejecutar una tarea, sino que vuelven al pool.
  • Balanceo de carga — las tareas se distribuyen de manera uniforme.
  • Gestión de recursos — se limita la cantidad de hilos ejecutándose simultáneamente.


Implementación básica de una cola de tareas en C++

Veamos una cola de tareas simple pero segura para multihilo usando std::queue y mutex. Para ello, utilizamos la biblioteca estándar de C++11 y posteriores.



#include <queue>#include <mutex>#include <condition_variable>#include <functional>#include <thread>#include <vector>

class TaskQueue {public: using Task = std::function<void()>;

explicit TaskQueue(size_t numThreads) : stop(false) { for (size_t i = 0; i < numThreads; ++i) { workers.emplace_back([this] { workerLoop(); }); } }

~TaskQueue() { { std::unique_lock<std::mutex> lock(mutex); stop = true; } condition.notify_all(); for (auto& worker : workers) { if (worker.joinable()) { worker.join(); } } }

void enqueue(Task task) { { std::unique_lock<std::mutex> lock(mutex); tasks.push(std::move(task)); } condition.notify_one(); }

private: void workerLoop() { while (true) { Task task; { std::unique_lock<std::mutex> lock(mutex); condition.wait(lock, [this] { return stop || !tasks.empty(); }); if (stop && tasks.empty()) { return; } task = std::move(tasks.front()); tasks.pop(); } task(); // Ejecución de la tarea } }

std::queue<Task> tasks; std::mutex mutex; std::condition_variable condition; bool stop; std::vector<std::thread> workers;};


Ejemplo de uso

Ahora mostramos cómo usar nuestra clase TaskQueue para ejecutar cálculos simples en paralelo:



#include <iostream>

int main() { TaskQueue tq(4); // Pool de 4 hilos

for (int i = 0; i < 10; ++i) { tq.enqueue([i] { std::cout << "Tarea " << i << " ejecutada por el hilo " << std::this_thread::get_id() << std::endl; }); }

// El destructor de tq esperará a que todas las tareas terminen return 0;}


Funcionalidades avanzadas: cola con prioridades

A veces es necesario procesar las tareas según su importancia. Para ello, se puede usar std::priority_queue en lugar de una cola normal. Añadimos soporte para prioridades:



#include <queue>#include <functional>

class PriorityTaskQueue {public: using Task = std::function<void()>;

struct PrioritizedTask { int priority; Task t

Recommendations