线程池通过复用线程执行任务以减少开销,核心包括线程集合、任务队列、互斥锁、条件变量和控制标志;submit方法提交任务并返回future获取结果,析构时安全关闭确保任务完成。

实现一个线程池的核心目标是:复用一组线程来执行多个任务,避免频繁创建和销毁线程带来的开销。在C++中,可以借助std::thread、std::queue、std::mutex、std::condition_variable和std::function等工具完成一个高效且线程安全的线程池。
一个典型的线程池包含以下几个部分:
std::function<void()>类型)。用户通过submit方法提交可调用对象(如lambda、函数指针、bind表达式),线程池将其包装为std::function放入队列。工作线程循环等待任务,一旦获取到任务就立即执行。
使用std::packaged_task可以方便地获取任务的返回值,通过std::future机制实现异步结果获取。
立即学习“C++免费学习笔记(深入)”;
示例代码片段:
template <typename F>
auto submit(F&& f) -> std::future<decltype(f())> {
using ReturnType = decltype(f());
auto task = std::make_shared<std::packaged_task<ReturnType()>>(std::forward<F>(f));
std::future<ReturnType> result = task->get_future();
{
std::unique_lock<std::mutex> lock(queue_mutex);
if (stop) throw std::runtime_error("submit on stopped ThreadPool");
tasks.emplace([task]() { (*task)(); });
}
condition.notify_one();
return result;
}
构造函数中启动指定数量的工作线程,每个线程运行一个无限循环,从任务队列中取任务执行。
析构函数需要妥善处理未完成的任务:
stop标志位,防止新任务提交。join(),确保它们正常退出。这样可以保证已提交的任务被执行完毕,避免资源泄漏或程序崩溃。
以下是一个简单的使用场景:
ThreadPool pool(4); // 创建4个线程的线程池
<p>std::vector<std::future<int>> results;
for (int i = 0; i < 8; ++i) {
results.emplace_back(
pool.submit([i] {
std::this_thread::sleep_for(std::chrono::seconds(1));
return i * i;
})
);
}</p><p>for (auto& result : results) {
std::cout << result.get() << ' ';
}
// 输出: 0 1 4 9 16 25 36 49</p>这段代码提交了8个计算任务,由4个线程并发执行,最后收集结果。
基本上就这些。一个简洁高效的C++线程池不需要复杂设计,关键是正确处理并发同步和资源释放。
以上就是C++怎么实现一个线程池_C++并发编程与线程池实现的详细内容,更多请关注php中文网其它相关文章!
编程怎么学习?编程怎么入门?编程在哪学?编程怎么学才快?不用担心,这里为大家提供了编程速学教程(入门课程),有需要的小伙伴保存下载就能学习啦!
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号