我的问题来自C++11 中 ThreadPool 类的实现。以下是代码中的相关部分:
- 每当
enqueue
在 threadPool 对象上调用时,它会将传递的函数与所有传递的参数绑定,以创建 ashared_ptr
ofstd::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
在 a 中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
存储在 a 中std::queue<std::function<void()>>
,那么它就变成了一个std::function
对象,对吧?那么它如何仍然写入std::future
之前提取的共享状态?如果 stored
std::packaged_task
不只是一个std::function
对象,而且还是一个std::packaged_task
then 当 a通过 lambdastd::thread
执行task()
(构造函数中的代码),那么为什么它不在另一个线程上运行呢?std::packaged_task
应该在另一个线程上运行,对吗?
正如我的问题所暗示的那样,我无法理解 into 的std::packaged_task
转换std::function
以及std::function
写入std::future
. 每当我用 n 个线程测试这段代码时,我可以获得的最大线程 ID 数是 n,但不会超过 n。这是完整的代码(包括的代码,ThreadPool
它还包括一个计算创建的线程数的主函数)。