C++实现简单的线程池
#include <iostream>
#include <thread>
#include <functional>
#include <mutex>
#include <vector>
#include <list>
#include <cassert>
class TaskQueue {
public:
TaskQueue() = default;
virtual ~TaskQueue() = default;
virtual void enqueue(std::function<void()> fn) = 0;
virtual void shutdown() = 0;
virtual void on_idle() {}
};
class ThreadPool : public TaskQueue {
public:
explicit ThreadPool(size_t n) : shutdown_(false) {
while (n)
{
threads_.emplace_back(worker(*this));
n--;
}
}
ThreadPool(const ThreadPool&) = delete;
~ThreadPool() override = default;
void enqueue(std::function<void()> fn) override {
std::unique_lock<std::mutex> lock(mutex_);
jobs_.push_back(std::move(fn));
cond_.notify_one();
}
void shutdown() override {
{
std::unique_lock<std::mutex> lock(mutex_);
shutdown_ = true;
}
cond_.notify_all();
for (auto& t : threads_)
{
t.join();
}
}
private:
struct worker {
explicit worker(ThreadPool& pool) :pool_(pool) {}
void operator()() {
for (;;)
{
std::function<void()> fn;
{
std::unique_lock<std::mutex> lock(pool_.mutex_);
pool_.cond_.wait(lock,
[&] {
return !pool_.jobs_.empty() || pool_.shutdown_;
});
if (pool_.shutdown_ && pool_.jobs_.empty()) break;
fn = pool_.jobs_.front();
pool_.jobs_.pop_front();
}
assert(true == static_cast<bool>(fn));
fn();
}
}
ThreadPool& pool_;
};
friend struct worker;
std::mutex mutex_;
std::condition_variable cond_;
std::vector<std::thread> threads_;
std::list<std::function<void()>> jobs_;
bool shutdown_;
};
int main()
{
std::mutex mtx_;
int x = 0;
std::unique_ptr<TaskQueue> task_queue(new ThreadPool(size_t(std::thread::hardware_concurrency() - 1)));
for (int i = 0; i < 10; i++) {
task_queue->enqueue([=, &x, &mtx_]() {
++x;
std::lock_guard<std::mutex> lock(mtx_);
std::cout << "x = " << x <<"\n";
});
}
std::cin.get();
}