我的问题来自C ++ 11中ThreadPool类的this实现。以下是代码中的相关部分:
enqueue
时,它会将传递的函数与所有传递的参数绑定在一起,以创建shared_ptr
的{{1}}:std::packaged_task
从此 auto task = std::make_shared< std::packaged_task<return_type()> >(
std::bind(std::forward<F>(f), std::forward<Args>(args)...)
);
中提取future
以返回到调用方,并将此std::packaged_task
存储在task
中。
在构造函数中,它等待队列中的任务,如果找到一个,则执行任务:
std::queue<std::function<void()>> tasks;
现在,基于此,以下是我的问题:
如果 for(size_t i = 0;i<threads;++i)
workers.emplace_back(
[this]
{
for(;;)
{
std::function<void()> task;
{
std::unique_lock<std::mutex> lock(this->queue_mutex);
this->condition.wait(lock,[this]{ return !this->tasks.empty(); });
task = std::move(this->tasks.front());
this->tasks.pop();
}
task();
}
}
);
存储在std::packaged_task
中,那么它就变成了std::queue<std::function<void()>>
对象,对吗?那么它如何仍然写入先前提取的std::function
的共享状态?
如果存储的std::future
不仅是std::packaged_task
对象,而且还是std::function
,那么当std::packaged_task
通过lambda执行std::thread
时,task()
内部构造函数),那么为什么它不能在另一个线程上运行?因为std::packaged_task
应该在另一个线程上运行,对吧?
正如我的问题所建议的,我无法理解std::packaged_task
到std::function
的转换以及std::function
写入std::future
共享状态的能力。每当我用n个线程测试此代码时,我可以获得的最大线程ID数为n,但决不超过n。 Here是完整的代码(包括ThreadPool
的代码,并且还包括一个主要功能,用于计算创建的线程数)。