Функция прохода ThreadPool в качестве аргумента - PullRequest
0 голосов
/ 18 февраля 2019

Я пытаюсь реализовать свою собственную версию параллели для использования https://github.com/Fdhvdu/ThreadPool в качестве пула внутренних потоков

Я разделяю задачу на несколько частей и запускаю поток со следующимфункция:

template <typename Callable>
void launchRange(int id, Callable func, int k1, int k2)
{
    for (int k = k1; k < k2; k++) {
        func(k);
    }
}

У меня проблема в том, как передать это Callable в пул потоков

Соответствующая часть:

poolPtr->add(launchRange, func, i1, i2);

НоЯ продолжаю получать ошибки компиляции.Ошибка:

...\ithreadpoolitembase.hpp(36): error C2027: use of undefined type 'std::tuple<conditional<_Test,void(__cdecl *&)(int),_Ty>::type,conditional<_Test,int&,int>::type,conditional<_Test,int&,int>::type>'
with
[
    _Ty=void (__cdecl *)(int)
]

Интерфейс для add:

template<class Func,class ... Args>
inline thread_id add(Func &&func,Args &&...args);

Я использую Visual Studio 2017 Community 15.4 с /std:c++17

1 Ответ

0 голосов
/ 18 февраля 2019

launchRange - это шаблон функции, а не функция.

Вы не можете передать шаблон функции как функцию, если не было выполнено разрешение перегрузки.Эта строка не вызывает разрешение перегрузки.

auto launchRange = [](int id, auto&& func, int k1, int k2)
{
  for (int k = k1; k < k2; k++) {
    func(k);
  }
};

Выше приведена лямбда, которая во многом похожа на шаблон launchRange, но это фактический объект, а не просто шаблон.

Это все равно не будет работать, потому что вы не передаете add аргумент id.

poolPtr->add(launchRange, 77, func, i1, i2);

, который, вероятно, скомпилируется.

Мне это не особо нравитсяконкретная реализация пула потоков.Я имею в виду, сколько бессмысленных слоев прыщей вы можете иметь?Сколько бессмысленного выделения кучи?И это проходит по ссылке по умолчанию , что является ужасной идеей при передаче материала в другой поток.

Я бы сказал, что принятие аргументов - это плохой план.Избегайте их использования.

poolPtr->add([=]{ launchRange(77, func, i1, i2); });

, что также устраняет необходимость создания auto launchRange = [] лямбда.А ошибки в итоге становятся намного проще для чтения.

...