Делает ли async (launch :: async) в C ++ 11 пулами потоков устаревшими для избежания дорогостоящего создания потоков?

Это слабо связано с этим вопросом:Объединены ли std :: thread в C ++ 11?, Хотя вопрос отличается, намерение то же самое:

Вопрос 1. Имеет ли смысл использовать собственные (или сторонние библиотеки) пулы потоков, чтобы избежать дорогостоящего создания потоков?

В другом вопросе был сделан вывод, что нельзя полагаться наstd::thread быть объединенным (это может или не может быть). Тем не мение,std::async(launch::async) похоже, у вас гораздо больше шансов быть объединенным.

Не думаю, что это навязывается стандартом, но IMHO, я ожидаю, что все хорошие реализации C ++ 11 будут использовать пул потоков, если создание потоков будет медленным. Я предполагаю, что только на платформах, где создание нового потока недорого, они всегда создают новый поток.

Вопрос 2: Это именно то, что я думаю, но у меня нет фактов, чтобы это доказать. Я вполне могу ошибаться. Это обоснованное предположение?

Наконец, здесь я предоставил некоторый пример кода, который сначала показывает, как я думаю, что создание потока может быть выраженоasync(launch::async):

Пример 1:

 thread t([]{ f(); });
 // ...
 t.join();

становится

 auto future = async(launch::async, []{ f(); });
 // ...
 future.wait();

Пример 2: запустить и забыть нить

 thread([]{ f(); }).detach();

становится

 // a bit clumsy...
 auto dummy = async(launch::async, []{ f(); });

 // ... but I hope soon it can be simplified to
 async(launch::async, []{ f(); });

Вопрос 3: Вы бы предпочлиasync версии кthread версии?

Остальное больше не является частью вопроса, но только для уточнения:

Почему возвращаемое значение должно быть присвоено фиктивной переменной?

К сожалению, текущий стандарт C ++ 11 заставляет вас захватывать возвращаемое значениеstd::async, иначе выполняется деструктор, который блокируется до тех пор, пока действие не завершится. Это считается ошибкой в стандарте (например, Хербом Саттером).

Этот пример изcppreference.com хорошо иллюстрирует это:

{
  std::async(std::launch::async, []{ f(); });
  std::async(std::launch::async, []{ g(); });  // does not run until f() completes
}

Еще одно уточнение:

я знаю этоу пулов потоков может быть другое законное использование, но в этом вопросе меня интересует только аспект избежания дорогостоящих затрат на создание потоков.

Я думаю, что все еще существуют ситуации, когда пулы потоков очень полезны, особенно если вам нужен больший контроль над ресурсами. Например, сервер может решить обрабатывать только фиксированное количество запросов одновременно, чтобы гарантировать быстрое время отклика и повысить предсказуемость использования памяти. Пулы потоков должны быть в порядке, здесь.

Локальные переменные потока также могут быть аргументом для ваших собственных пулов потоков, но я не уверен, насколько это актуально на практике:

Создание новой темы сstd::thread начинается без инициализированных локальных переменных потока. Может быть, это не то, что вы хотите.В темах, порожденныхasync, это несколько неясно для меня, потому что поток мог быть использован повторно. Насколько я понимаю, локальные переменные потока не гарантированно сбрасываются, но я могу ошибаться.Использование собственных пулов потоков фиксированного размера, с другой стороны, дает вам полный контроль, если вам это действительно нужно.

Ответы на вопрос(1)

Ваш ответ на вопрос