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保护。但未来在获取数据时使用原子操作。因此,它将在赫尔格林失败。