这是从我对另一个非常相似的帖子的回答中复制的:
从系统可以支持的最大线程数开始:
int num_threads = std::thread::hardware_concurrency();
对于一个高效的线程池实现,一旦根据 线程创建num_threads
,最好不要创建新线程,或者销毁旧线程(通过加入)。会有性能损失,甚至可能使您的应用程序运行速度比串行版本慢。
每个 C++11 线程都应该在其函数中以无限循环运行,不断等待新任务的抓取和运行。
以下是如何将这样的函数附加到线程池:
int num_threads = std::thread::hardware_concurrency();
std::vector<std::thread> threads;
for (int i = 0; i < num_threads; i++)
{
pool.push_back(std::thread(Infinite_loop_function));
}
- 无限循环功能。这是一个
while (true)
等待任务队列的循环。
void Pool::Infinite_loop_function()
{
while (true)
{
{
std::unique_lock<std::mutex> lock(queue_mutex);
condition.wait(lock, [this](){
return !queue.empty() || terminate_pool;
});
Job = queue.front();
queue.pop();
}
Job(); // function<void()> type
}
};
- 制作一个将作业添加到队列的功能
void Pool::Add_Job(function<void()> New_Job)
{
{
std::unique_lock<std::mutex> lock(queue_mutex);
queue.push(New_Job);
}
condition.notify_one();
}
- 将任意函数绑定到您的队列
Pool_Obj.Add_Job(std::bind(&Some_Class::Some_Method, &Some_object));
一旦你整合了这些成分,你就有了自己的动态线程池。这些线程始终运行,等待工作完成。
如果有一些语法错误,我深表歉意,我输入了这段代码,我记性不好。抱歉,我无法为您提供完整的线程池代码;那会违反我的职业操守。
编辑:终止池,调用shutdown()
方法:
Pool::shutdown()
{
{
std::unique_lock<std::mutex> lock(threadpool_mutex);
terminate_pool = true; // use this flag in condition.wait
}
condition.notify_all(); // wake up all threads.
// Join all threads.
for (std::thread &th : threads)
{
th.join();
}
pool.clear();
stopped = true; // use this flag in destructor, if not set, call shutdown()
}
注意:使用匿名代码块,以便当它们退出时,std::unique_lock
在其中创建的变量会超出范围,从而解锁互斥锁。