C++线程池的简单实现。
完整代码:https://github.com/ocfBNj/ThreadPool
线程池(英语:thread pool):一种线程使用模式。线程过多会带来调度开销,进而影响缓存局部性和整体性能。而线程池维护着多个线程,等待着监督管理者分配可并发执行的任务。这避免了在处理短时间任务时创建与销毁线程的代价。线程池不仅能够保证内核的充分利用,还能防止过分调度。线程数一般取cpu数量+2比较合适,线程数过多会导致额外的线程切换开销。
上面是维基百科对线程池的介绍。
使用std::thread::hardware_concurrency()获得系统支持的最大线程数量。
因为线程的创建和摧毁需要时间开销。对于一个高效的线程池,一次性创建size个线程,并且在之后不再创建新的线程或摧毁旧的线程。每个线程池中的线程中通过无限循环的函数从任务队列中取走并执行任务。
当任务队列为空时,阻塞直到任务队列不为空或线程池被停止(即将被销毁)。
当线程池被停止时,执行完未完成的任务,然后退出该无限循环函数。
从任务队列取出一个任务后,执行它。
停止线程池并通知线程池中的线程。
等待线程池中的线程执行完毕。
start函数将一个任务(函数)添加到任务队列中,并通过std::future获得该任务的返回值。
std::packaged_task打包一个可调用目标(如函数,lambda表达式,bind表达式或其他函数对象),它的返回值可以通过std::future获得。
使用智能指针std::shared_ptr共享std::packaged_task对象(因为它不可拷贝,且在lambda表达式中被共享)。
最后通过std::condition_variable通知线程池中的线程有新任务到达。
简单的测试代码:
#include <chrono> #include <iostream> #include <vector> #include "ThreadPool.h" constexpr int n = 20'000; void task(int arg) { for (volatile int i = 0; i != arg; i++) { ; } } void testThreadPool() { std::vector<std::future<void>> ret; ThreadPool pool; auto begin = std::chrono::high_resolution_clock::now(); for (volatile int i = 0; i != n; i++) { ret.emplace_back(pool.start(task, 10'000)); } for (auto& future : ret) { future.get(); } auto end = std::chrono::high_resolution_clock::now(); auto time = std::chrono::duration_cast<std::chrono::milliseconds>(end - begin); std::cout << "thread pool: " << time.count() / 1000.0 << "s\n"; } void testThread() { std::vector<std::thread> ret; auto begin = std::chrono::high_resolution_clock::now(); for (volatile int i = 0; i != n; i++) { ret.emplace_back(task, 10'000); } for (auto& thread : ret) { thread.join(); } auto end = std::chrono::high_resolution_clock::now(); auto time = std::chrono::duration_cast<std::chrono::milliseconds>(end - begin); std::cout << "only thread: " << time.count() / 1000.0 << "s\n"; } int main() { using namespace std::literals; testThread(); std::this_thread::sleep_for(5s); testThreadPool(); }可能的输出:
only thread: 0.985s thread pool: 0.177shttps://stackoverflow.com/questions/15752659/thread-pooling-in-c11
https://github.com/progschj/ThreadPool
https://cppreference.com