QtConcurrent :: ошибка сегментации карты - PullRequest
0 голосов
/ 20 сентября 2018

Когда я пытался реализовать «параллельное для» с использованием QtConcurrent :: map:

QFuture<void> parForAsync(size_t n, std::function<void (size_t)> Op)
{

    size_t nThreads =
            static_cast<size_t>(QThreadPool::globalInstance()->maxThreadCount());
    size_t nn = n/nThreads + 1;

    using Sequence = QVector<std::function<void()>>;
    Sequence vFuns;

    for(size_t i = 0; i < n; i+=nn)
    {
        size_t firstIdx = i,
                lastIdx = i + nn > n ? n : i + nn;

        vFuns.push_back([=]()->void
        {
            for(size_t i = firstIdx; i < lastIdx; ++i)
            {
                Op(i);
            }
        });
    }
    return QtConcurrent::map<Sequence>    //<-Segmentation fault!
            (vFuns, [](std::function<void()> f)
    {
        f();
    });
}

У меня ошибка сегментации в этом месте:

template<typename _Res, typename... _ArgTypes>
    function<_Res(_ArgTypes...)>::
    function(const function& __x)
    : _Function_base()
    {
      if (static_cast<bool>(__x))
    {
      __x._M_manager(_M_functor, __x._M_functor, __clone_functor); //<-Segmentation fault!
      _M_invoker = __x._M_invoker;
      _M_manager = __x._M_manager;
    }
    }

Почемуэто происходит?Похоже, что std :: function прошел проверку.Как я могу заставить этот код работать?

Заранее спасибо!

1 Ответ

0 голосов
/ 20 сентября 2018

Я не могу воспроизвести ваш случай, но я могу привести вам пример, иллюстрирующий проблему

QFuture<void> test ()
{   
    QVector<int> v; // LOCAL VARIABLE IN SCOPE OF test FUNCTION

    // preparing v vector

    QFuture<void> f = QtConcurrent::map(v,someFunction); // returns immediately
    return f;
}

[1] QtConcurrent::map занимает v по ссылке NOT BY COPY.

[2] QtConcurrent::map немедленно возвращается.

[3] Таким образом, когда функция test заканчивается, параллельные операции, запускаемые map, используют вектор v, который был удален, поскольку он является локальной переменной в функции test.

Вы можете использовать waitForFinished для QFuture, но тогда ваша функция не имеет смысла, потому что она блокируется до завершения параллельной задачи.

...