Как вернуть будущее при отправке в пул потоков - PullRequest
3 голосов
/ 30 апреля 2020

Я пытаюсь выполнить sh задачу с возвращаемым значением в пул потоков:

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;
}

И l oop выглядит так:

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;
        }
    }
}

Хелгринд жалуется о гонке данных при попытке ожидания результата:

возможная гонка данных при чтении размером 8 в 0x5DFB618 потоком # 1

Это конфликтует с предыдущей записью размера 8 thread # 2

Это ложное срабатывание или есть какая-то проблема с реализацией выше?

1 Ответ

0 голосов
/ 01 мая 2020

Я не вижу гонки данных в вашем коде. Проблема может быть где-то еще. Как изменение m_terminate без надлежащей синхронизации.

Это также может быть ложным срабатыванием. Согласно документации , Helgrind обнаруживает ошибки синхронизации в программах, использующих потоковые примитивы POSIX pthreads. Таким образом, Helgrind может не распознать, что определенный фрагмент кода правильно синхронизирован, если он не использует примитивы pthread.

Механизмы синхронизации, такие как std::mutex, std::condition_variable, std::atomic et c, могут или могут быть не использовать примитивы pthread при их реализации. В частности, std::atomic s, скорее всего, нет.

Я советую вам использовать ThreadSanitizer вместо Helgrind для обнаружения ошибок потоков.

...