Skip to content

Instantly share code, notes, and snippets.

@jesustorresdev
Created March 28, 2016 16:20
Show Gist options
  • Save jesustorresdev/dd6e8486fda7b9d77f54 to your computer and use it in GitHub Desktop.
Save jesustorresdev/dd6e8486fda7b9d77f54 to your computer and use it in GitHub Desktop.
Ejemplo de pool de hilos en C++
#include <iostream>
#include <condition_variable>
#include <mutex>
#include <queue>
#include <thread>
#include <memory>
#include <vector>
#include "unistd.h"
#include "printtask.h"
#include "task.h"
// Número de hilos
const int NUM_OF_THREADS = 10;
// const int NUM_OF_THREADS = std::thread::hardware_concurrency();
// Cola de tareas
std::queue<std::unique_ptr<Task>> task_queue;
std::mutex queue_mutex;
std::condition_variable non_empty_task_queue;
void threadpool_exec()
{
while(true) {
std::unique_lock<std::mutex> lock(queue_mutex);
while (task_queue.empty())
non_empty_task_queue.wait(lock);
// Sacamos la siguiente tarea
auto task = std::move(task_queue.front());
task_queue.pop();
// Desbloqueamos para que los run() se puedan ejecutar en paralelo
lock.unlock();
task->run();
}
}
int main()
{
std::vector<std::thread> threadpool;
for(int i = 0; i < NUM_OF_THREADS; ++i) {
threadpool.push_back(std::thread(&threadpool_exec));
// No queremos preocuparnos por la terminación de los hilos
threadpool.back().detach();
// // Alternativamente
// auto thread = std::thread(&threadpool_exec);
// thread.detach();
// threadpool.push_back(std::move(thread));
}
// Insertamos 1000 tareas.
for(int i = 0; i < 1000; ++i) {
usleep(600);
std::lock_guard<std::mutex> lock(queue_mutex);
std::string message = "Hola Mundo" + std::to_string(i);
task_queue.push(std::unique_ptr<Task>(new PrintTask(message)));
// Como sólo hemos añadido una tarea, despertamos a un único hilo
non_empty_task_queue.notify_one();
// non_empty_task_queue.notify_all();
}
// Esperar a que se hagan todas las tareas antes de terminar
while(true) {
std::unique_lock<std::mutex> lock(queue_mutex);
if (task_queue.empty())
break;
lock.unlock();
usleep(100000);
}
return 0;
}
#ifndef PRINTTASK_H
#define PRINTTASK_H
#include <iostream>
#include <string>
#include <thread>
#include <unistd.h>
#include "task.h"
class PrintTask : public Task
{
public:
PrintTask(const std::string& msg) : msg_(msg) {}
void run()
{
std::cout << std::this_thread::get_id() << ": " << msg_ << std::endl;
usleep(1000); // Para simular que la tarea dura un tiempo.
}
private:
const std::string msg_;
};
#endif // PRINTTASK_H
#ifndef TASK_H
#define TASK_H
class Task
{
public:
virtual void run() = 0;
};
#endif // TASK_H
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment