C++ 如何在推送到线程池时返回未来
我尝试将具有返回值的任务推送到线程池:C++ 如何在推送到线程池时返回未来,c++,multithreading,promise,future,C++,Multithreading,Promise,Future,我尝试将具有返回值的任务推送到线程池: template<class Function> auto enqueue(Function&& f) { using ReturnType = std::result_of_t<std::decay_t<Function>()>; std::promise<ReturnType> ret_promise; auto fut = ret_promise.get_futu
template<class Function>
auto enqueue(Function&& f)
{
using ReturnType = std::result_of_t<std::decay_t<Function>()>;
std::promise<ReturnType> ret_promise;
auto fut = ret_promise.get_future();
auto task = UniqueFunction<void()>(
[do_it = std::move(f), ret = std::move(ret_promise)]() mutable {
ret.set_value(do_it());
});
{
std::lock_guard lock{m_mtx};
m_tasks.push(std::move(task));
m_cv.notify_one();
}
return fut;
}
模板
自动排队(函数(&f)
{
使用ReturnType=std::result\u of\u t;
std::承诺再承诺;
auto fut=ret_promise.get_future();
自动任务=唯一功能(
[do_it=std::move(f),ret=std::move(ret_promise)]()可变{
ret.set_值(do_it());
});
{
std::lock_guard lock{m_mtx};
m_tasks.push(std::move(task));
m_cv.通知_one();
}
返回fut;
}
循环如下所示:
void performTasks()
{
while(true)
{
std::unique_lock<std::mutex> lock{m_mtx};
m_cv.wait(lock, [this]() { return !m_tasks.empty() || m_terminate; });
if(!m_tasks.empty())
{
auto task = std::move(m_tasks.front());
m_tasks.pop();
lock.unlock();
task();
}
else
{
return;
}
}
}
void performtask()
{
while(true)
{
std::unique_lock lock{m_mtx};
m|cv.wait(lock,[this](){return!m|u tasks.empty()| m|u terminate;});
如果(!m_tasks.empty())
{
自动任务=std::move(m_tasks.front());
m_tasks.pop();
lock.unlock();
任务();
}
其他的
{
返回;
}
}
}
Helgrind在等待结果时抱怨数据竞争:
线程#1在0x5DFB618读取大小8时可能存在数据争用
这与之前通过线程#2进行的大小为8的写入冲突
这是一个误报还是上面的实现存在一些问题?我在代码中看不到数据竞争。问题可能在其他地方。如修改
m_terminate
而不进行适当的同步
也可能是假阳性。根据,Helgrind在使用POSIX pthreads线程原语的程序中检测同步错误。因此,如果不使用pthread原语,Helgrind可能无法识别特定代码段是否正确同步
像std::mutex
,std::condition\u variable
,std::atomic
等同步机制在其实现中可能使用也可能不使用pthread原语。特别是,std::atomic
s很可能不会
我建议您使用而不是Helgrind来检测线程错误。请发布完整的工作示例。使用ThreadSanitizer运行代码时,没有问题。是的,它是std::atomic。std::mutex和std::condition_变量在引擎盖下使用pthread.is
m_terminate
a原子布尔?否,但由相同的mutex保护。但未来在获取数据时使用原子操作。因此,它将在赫尔格林失败。