c++11 线程池系列之一 所需要的join_threads

本文介绍了一个实用的C++类join_threads,用于确保所有线程正确结束。该类通过析构函数遍历线程集合并调用join()方法来等待每个线程完成。这对于避免资源泄露和确保程序稳定退出至关重要。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

class join_threads
{
std::vector<std::thread> &threads;
public:
	explicit join_threads(std::vector<std::thread> &threads_):threads(threads_){}
	~join_threads()
	{
	for(unsigned long i = 0 ; i < threads.size();++i)
	{
	if(threads[i].joinable())
		threads[i].join();
	}
	}
};

### C++11线程池的实现方法 C++11 提供了 `std::thread` 和其他同步工具(如 `std::mutex`, `std::condition_variable`),使得我们可以轻松构建一个多线程环境下的线程池。以下是基于引用内容的一个完整的线程池实现示例。 #### 线程池类定义 线程池的核心是一个工作队列和一组工作线程。通过构造函数初始化这些线程,并让它们不断从任务队列中获取新任务执行[^1]。 ```cpp #include <iostream> #include <vector> #include <queue> #include <thread> #include <atomic> #include <functional> #include <future> #include <memory> class ThreadPool { public: /// @brief 构造函数,创建指定数量的工作线程 explicit ThreadPool(size_t threads = std::thread::hardware_concurrency()) : stop(false) { if (threads == 0) { threads = 1; } for (size_t i = 0; i < threads; ++i) { workers.emplace_back([this] { while (true) { std::function<void()> task; { std::unique_lock<std::mutex> lock(this->mutex); this->condition.wait(lock, [this] { return this->stop || !this->tasks.empty(); }); if (this->stop && this->tasks.empty()) { return; } task = std::move(this->tasks.front()); this->tasks.pop(); } task(); } }); } } ~ThreadPool() { { std::unique_lock<std::mutex> lock(mutex); stop = true; } condition.notify_all(); for (std::thread &worker : workers) { worker.join(); } } /// @brief 添加任务到线程池的任务队列中 template<class F, class... Args> auto enqueue(F&& f, Args&&... args) -> std::future<typename std::result_of<F(Args...)>::type> { using return_type = typename std::result_of<F(Args...)>::type; auto task = std::make_shared<std::packaged_task<return_type()>>( std::bind(std::forward<F>(f), std::forward<Args>(args)...) ); std::future<return_type> res = task->get_future(); { std::unique_lock<std::mutex> lock(mutex); if (stop) { throw std::runtime_error("enqueue on stopped ThreadPool"); } tasks.emplace([task]() { (*task)(); }); } condition.notify_one(); return res; } private: std::vector<std::thread> workers; std::queue<std::function<void()>> tasks; std::mutex mutex; std::condition_variable condition; bool stop; }; ``` --- #### 关键点解析 1. **线程初始化** 在构造函数中,通过循环创建多个线程并将其加入到 `workers` 容器中。每个线程会持续等待新的任务到来,并在接收到任务后立即执行它。 2. **任务提交机制** 使用模板函数 `enqueue` 来支持任意类型的可调用对象作为任务提交给线程池。该函数返回一个 `std::future` 对象,允许主线程异步接收任务的结果[^2]。 3. **停止条件** 当销毁线程池时,设置标志位 `stop=true` 并通知所有线程退出循环。随后调用 `join()` 方法确保所有子线程安全结束。 4. **线程安全性** 利用了互斥锁 (`std::mutex`) 和条件变量 (`std::condition_variable`) 来保护共享资源访问的安全性,防止数据竞争问题发生。 --- #### 示例代码运行方式 下面展示如何使用上述线程池来并发计算一些简单的任务: ```cpp int main() { ThreadPool pool(4); // 创建具有4个工作线程线程池 std::vector<std::future<int>> results; for (int i = 0; i < 8; ++i) { results.push_back(pool.enqueue([](int value) { return value * value; }, i)); } for (auto& result : results) { try { std::cout << "Result: " << result.get() << "\n"; } catch (...) { std::cerr << "Task threw an exception.\n"; } } return 0; } ``` 此程序将启动四个线程处理八个平方运算任务,并最终打印每项任务的结果。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值