这个线程池代码是不是尝试双重执行任务?
Posted
技术标签:
【中文标题】这个线程池代码是不是尝试双重执行任务?【英文标题】:Is this threadpool code attempting double execution of task?这个线程池代码是否尝试双重执行任务? 【发布时间】:2021-10-04 19:27:00 【问题描述】:我从https://pastebin.com/MM5kSvH6 复制了以下线程池实现。一切看起来都不错,但我无法理解第 32 行和第 71 行的逻辑。这两行不是都在尝试执行该功能吗?我想在线程池中,线程应该从任务队列中提取任务然后执行它?从这个意义上说,第 71 行看起来不错,但我对第 32 行感到困惑。为什么不将任务添加到队列中,为什么要尝试执行相同的操作?
#include <condition_variable>
#include <functional>
#include <iostream>
#include <future>
#include <vector>
#include <thread>
#include <queue>
class ThreadPool
public:
using Task = std::function<void()>;
explicit ThreadPool(std::size_t numThreads)
start(numThreads);
~ThreadPool()
stop();
template<class T>
auto enqueue(T task)->std::future<decltype(task())>
auto wrapper = std::make_shared<std::packaged_task<decltype(task()) ()>>(std::move(task));
std::unique_lock<std::mutex> lockmEventMutex;
mTasks.emplace([=]
(*wrapper)();
);
mEventVar.notify_one();
return wrapper->get_future();
private:
std::vector<std::thread> mThreads;
std::condition_variable mEventVar;
std::mutex mEventMutex;
bool mStopping = false;
std::queue<Task> mTasks;
void start(std::size_t numThreads)
for (auto i = 0u; i < numThreads; ++i)
mThreads.emplace_back([=]
while (true)
Task task;
std::unique_lock<std::mutex> lockmEventMutex;
mEventVar.wait(lock, [=] return mStopping || !mTasks.empty(); );
if (mStopping && mTasks.empty())
break;
task = std::move(mTasks.front());
mTasks.pop();
task();
);
void stop() noexcept
std::unique_lock<std::mutex> lockmEventMutex;
mStopping = true;
mEventVar.notify_all();
for (auto &thread : mThreads)
thread.join();
;
int main()
ThreadPool pool36;
for (auto i = 0; i < 36; ++i)
pool.enqueue([]
auto f = 1000000000;
while (f > 1)
f /= 1.00000001;
);
return 0;
【问题讨论】:
这两行(32 和 71)都在 lambda 中。 @tkausl - 想更详细一点吗? 将lambda放入队列,线程池调用lambda。 @tkausl - 仍然不清楚为什么代码会尝试双重执行。你的答案没有解释清楚。第 31 行看起来像调用函数 (*wrapper)(); .不是吗?第 72 行在逻辑上是正确的,因为它是从队列中实际执行的正确位置。 第 31 行 正在 调用函数。 【参考方案1】:第 32 行添加了一个 lambda,它在调用时执行任务,而第 71 行执行 lambda。一个简单地委托给另一个。 简而言之,第 32 行只是 lambda 的一部分,它通过第 72 行的调用执行。我们没有双重执行。相反,第 72 行是执行第 32 行所属的代码的行。
【讨论】:
以上是关于这个线程池代码是不是尝试双重执行任务?的主要内容,如果未能解决你的问题,请参考以下文章