技术点
- 采用queue作为一个队列,生产者消费者模式
- std::condition_variable条件变量代替Linux Pthread库中的pthread_cond_*()函数提供条件变量相关的功能
- C++11风格的std::function,后续可以改造成templete模板方法
代码实现
// ThreadPool.h
#ifndef THREADPOOL_H
#define THREADPOOL_H
#include <functional>
#include <vector>
#include <thread>
#include <mutex>
#include <condition_variable>
#include <queue>
namespace icharle {
class ThreadPool {
public:
using Task = std::function<void()>;
ThreadPool(int threadNum);
bool addTask(const Task &);
~ThreadPool();
private:
void Run(ThreadPool *);
private:
bool _stop;
std::vector<std::thread> _threads;
std::mutex _mutex;
std::condition_variable _cond;
std::queue<Task> _tasks;
};
}
#endif //THREADPOOL_H
// ThreadPool.cpp
#include "ThreadPool.h"
namespace icharle {
ThreadPool::ThreadPool(int threadNum) :
stop(false),
_threads(threadNum) {
for (int i = 0; i < threadNum; ++i) {
_threads[i] = thread(Run, this);
}
}
void ThreadPool::Run(ThreadPool *pool) {
while (true) {
std::unique_lock<std::mutex> lock(pool->_mutex);
while (!pool->_stop && pool->_tasks.empty()) {
pool->_cond.wait(lock);
}
if (pool->_stop && pool->_tasks.empty()) {
return;
}
Task nextTask = pool->_tasks.front();
pool->_tasks.pop();
lock.unlock();
nextTask();
}
}
bool ThreadPool::addTask(const Task &) {
std::unique_lock<std::mutex> lock(_mutex);
if (!stop) {
_tasks.emplace(Task);
lock.unlock();
_cond.notify_one();
return true;
}
return false;
}
ThreadPool::~ThreadPool() {
std::unique_lock<std::mutex> lock(_mutex);
_stop = true;
lock.unlock();
_cond.notify_all();
for (size_t i = 0; i < _threads.size(); ++i) {
_threads[i].join();
}
}
}