Created
March 28, 2016 16:20
-
-
Save jesustorresdev/dd6e8486fda7b9d77f54 to your computer and use it in GitHub Desktop.
Ejemplo de pool de hilos en C++
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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