c++线程池其实大体意思很好理解,但是具体分析到代码上非常难懂,尤其对于初学者而言,设计很多c++11 c++14的标准,很复杂,但是如果弄明白了,多线程编程的水平就开始有起色,作者将来会出一个视频专讲线程池,作者水平不高,所以学的时候非常难懂,找各种资料,与ai对话,现在总算是弄明白了,希望大家不要走弯路,以后会讲一个视频的
#include <iostream>
#include <vector>
#include <queue>
#include <thread>
#include <mutex>
#include <condition_variable>
#include <functional>
#include <future>
#include <atomic>
using namespace std;
class ThreadPool {
public:
// 构造函数,初始化线程池,创建指定数量的线程
ThreadPool(size_t numThreads) : stop(false) {
for (size_t i = 0; i < numThreads; ++i) {
// 创建线程并加入线程池
workers.emplace_back([this] {
while (true) {
function<void()> task;
{
// 加锁以访问任务队列
unique_lock<mutex> lock(this->queueMutex);
// 等待有任务到来或者线程池停止
this->condition.wait(lock, [this] { return this->stop || !this->tasks.empty(); });
// 如果线程池停止且任务队列为空,则退出线程
if (this->stop && this->tasks.empty())
return;
// 从任务队列中取出一个任务
task = move(this->tasks.front());
this->tasks.pop();
}
// 执行任务
task();
}
});
}
}
// 析构函数,停止线程池并等待所有线程完成任务
~ThreadPool() {
{
unique_lock<mutex> lock(queueMutex);
stop = true;
}
// 通知所有线程停止等待
condition.notify_all();
// 等待所有线程完成任务
for (thread& worker : workers) {
worker.join();
}
}
// 向线程池添加任务
template<class F, class... Args>
auto enqueue(F&& f, Args&&... args)
-> future<typename invoke_result<F, Args...>::type> {
using return_type = typename invoke_result<F, Args...>::type;
// 封装任务
auto task = make_shared< packaged_task<return_type()> >(
bind(forward<F>(f), forward<Args>(args)...)
);
// 获取任务的未来结果
future<return_type> res = task->get_future();
{
unique_lock<mutex> lock(queueMutex);
// 线程池停止后不允许再添加任务
if (stop)
throw runtime_error("enqueue on stopped ThreadPool");
// 将任务添加到任务队列
tasks.emplace([task]() { (*task)(); });
}
// 通知一个线程有新任务到来
condition.notify_one();
return res;
}
private:
// 工作线程集合
vector< thread > workers;
// 任务队列
queue< function<void()> > tasks;
// 互斥锁,用于保护任务队列
mutex queueMutex;
// 条件变量,用于线程间的同步
condition_variable condition;
// 线程池停止标志
atomic<bool> stop;
};
// 示例任务函数
void exampleTask(int id) {
cout << "Task " << id << " is running on thread " << this_thread::get_id() << endl;
this_thread::sleep_for(chrono::seconds(1));
cout << "Task " << id << " is completed." << endl;
}
int main() {
// 创建一个包含 4 个线程的线程池
ThreadPool pool(4);
// 向线程池添加 8 个任务
vector< future<void> > futures;
for (int i = 0; i < 8; ++i) {
futures.emplace_back(pool.enqueue(exampleTask, i));
}
// 等待所有任务完成
for (auto& future : futures) {
future.wait();
}
return 0;
}