线程池主要包含一个线程数组、一个任务队列,接口添加任务,分发给线程;通过条件变量和flag唤醒线程。
参考了知乎与Github的代码,一个较简易的实现:
#include <atomic>
#include <condition_variable>
#include <functional>
#include <queue>
#include <thread>
#include <vector>
class Pool {
public:
Pool(const int thread_num = 6) : thread_num_(thread_num) {
while (threads_.size() < thread_num_) {
threads_.emplace_back([this] {
for (;;) {
std::function<void()> task;
{
std::unique_lock<std::mutex> lck(this->mtx_);
this->cond_var_.wait(lck, [this] {
return this->is_stoped || !this->tasks_.empty();
});
if (this->is_stoped || this->tasks_.empty()) {
return;
}
task = std::move(this->tasks_.front());
this->tasks_.pop();
}
task();
};
});
}
}
template <typename F, typename... Args>
void Add(F &&f, Args &&... args) {
if (is_stoped) {
return;
}
std::unique_lock<std::mutex> lck(this->mtx_);
tasks_.push([=]() { f(args...); });
cond_var_.notify_all();
}
void Stop() {
is_stoped = true;
std::unique_lock<std::mutex> lck(this->mtx_);
while (!tasks_.empty()) {
tasks_.pop();
}
cond_var_.notify_all();
for(auto &t: threads_){
if(t.joinable()){
t.join();
}
}
}
~Pool() {
Stop();
threads_.clear();
}
private:
const int thread_num_;
std::mutex mtx_;
std::condition_variable cond_var_;
std::atomic_bool is_stoped{false};
std::vector<std::thread> threads_;
std::queue<std::function<void()>> tasks_;
};