#ifndef thread_pool_hpp
#define thread_pool_hpp
#include <stdio.h>
#include <vector>
#include <queue>
#include <thread>
#include <mutex>
#include <condition_variable>
#include <functional>
#define DEFAULT_SIZE 4
#define MAX_SIZE 8
class ThreadPool {
private:
std::vector<std::thread> thread_workers;
std::queue<std::function<void()>> tasks_queue;
std::mutex queue_mutex;
std::condition_variable condition_variable;
bool is_finish;
int thread_nums;
int work_thread_nums;
void Loop();
public:
ThreadPool();
~ThreadPool();
void run(const std::function<void()> &func);
void addThread();
void runTask(const std::function<void()> &task);
};
#endif /* thread_pool_hpp */
#include "thread_pool.hpp"
#include <iostream>
#include <unistd.h>
ThreadPool::ThreadPool(): thread_nums(DEFAULT_SIZE), work_thread_nums(0), is_finish(false) {
for (int i=0; i<thread_nums; i++) {
thread_workers.emplace_back([this]{ Loop(); });
}
}
ThreadPool::~ThreadPool() {
std::unique_lock<std::mutex> locker(queue_mutex);
is_finish = true;
locker.unlock();
condition_variable.notify_all();
for(auto &thread: thread_workers) {
thread.join();
}
}
void ThreadPool::Loop(){
while (true) {
std::function<void()> task;
std::unique_lock<std::mutex> locker(queue_mutex);
condition_variable.wait(locker, [this](){
return (!tasks_queue.empty() || is_finish);
});
if (is_finish && tasks_queue.empty()) {
return;
}
task = tasks_queue.front();
tasks_queue.pop();
locker.unlock();
runTask(task);
}
}
void ThreadPool::runTask(const std::function<void ()> &task) {
work_thread_nums++;
task();
work_thread_nums--;
}
void ThreadPool::addThread() {
std::unique_lock<std::mutex> locker(queue_mutex);
thread_workers.emplace_back([this]{ Loop(); });
locker.unlock();
}
void ThreadPool::run(const std::function<void()> &func) {
std::unique_lock<std::mutex> locker(queue_mutex);
tasks_queue.emplace(func);
locker.unlock();
condition_variable.notify_one();
}