cpp
// 引入必要的头文件
#include <iostream>
#include <vector>
#include <queue>
#include <thread>
#include <mutex>
#include <condition_variable>
#include <functional>
#include <atomic>
#include <string>
using namespace std;
// 定义一个任务类,封装了要执行的函数和参数
class Task {
public:
// 使用可变参数模板和完美转发构造函数
template<typename F, typename... Args>
Task(F&& f, Args&&... args) {
// 使用lambda表达式和std::bind将函数和参数绑定在一起
func = std::bind(std::forward<F>(f), std::forward<Args>(args)...);
}
// 执行任务
void run() {
func();
}
private:
// 使用std::function存储可调用对象
std::function<void()> func;
};
// 定义一个线程池类,管理一组线程和一个任务队列
class ThreadPool {
public:
// 构造函数,初始化线程池
ThreadPool(size_t size) : stop(false) {
// 根据指定的大小创建线程
for (size_t i = 0; i < size; i++) {
// 使用lambda表达式作为线程函数
workers.emplace_back([this] {
// 循环执行任务,直到线程池停止
while (true) {
// 定义一个任务指针
Task* task;
// 使用互斥锁保护任务队列的访问
{
std::unique_lock<std::mutex> lock(this->queue_mutex);
// 使用条件变量等待任务的到来,或者线程池的停止
this->condition.wait(lock, [this] {
return this->stop || !this->tasks.empty();
});
// 如果线程池停止,并且任务队列为空,就退出循环
if (this->stop && this->tasks.empty()) {
return;
}
// 从任务队列中取出一个任务
task = this->tasks.front();
this->tasks.pop();
}
// 执行任务
task->run();
// 释放任务的内存
delete task;
}
});
}
}
// 析构函数,销毁线程池
~ThreadPool() {
// 使用互斥锁保护stop变量的访问
{
std::unique_lock<std::mutex> lock(queue_mutex);
// 设置stop为true,表示线程池要停止
stop = true;
}
// 通知所有等待的线程
condition.notify_all();
// 等待所有线程结束
for (std::thread& worker : workers) {
worker.join();
}
}
// 向任务队列中添加一个任务
template<typename F, typename... Args>
void enqueue(F&& f, Args&&... args) {
// 创建一个任务对象,使用new分配内存
Task* task = new Task(std::forward<F>(f), std::forward<Args>(args)...);
// 使用互斥锁保护任务队列的访问
{
std::unique_lock<std::mutex> lock(queue_mutex);
// 将任务添加到队列中
tasks.push(task);
}
// 通知一个等待的线程
condition.notify_one();
}
private:
// 一组工作线程
std::vector<std::thread> workers;
// 一个任务队列
std::queue<Task*> tasks;
// 一个互斥锁,用于同步对任务队列的访问
std::mutex queue_mutex;
// 一个条件变量,用于等待和通知任务的到来
std::condition_variable condition;
// 一个原子布尔变量,用于表示线程池是否要停止
std::atomic<bool> stop;
};
// 定义一个简单的函数,用于打印一些信息
void print_info(std::thread::id id, const std::string& msg) {
// 使用互斥锁保护标准输出的访问
static std::mutex cout_mutex;
std::unique_lock<std::mutex> lock(cout_mutex);
// 打印线程的id和信息
std::cout << "Thread " << id << ": " << msg << std::endl;
}
// 定义一个main函数,用于测试线程池
int main() {
// 创建一个大小为4的线程池
ThreadPool pool(4);
// 向线程池中添加10个任务
for (int i = 0; i < 10; i++) {
// 使用lambda表达式作为任务的函数
pool.enqueue([i] {
std::thread::id id = std::this_thread::get_id();
// 调用print_info函数,传递当前线程的id和一个信息
print_info(id, "Hello from task " + std::to_string(i));
});
}
// 等待线程池的析构,自动结束所有线程
return 0;
}