В чем проблема с std :: async?

В начале этот клип из C ++ и далее, я слышал кое-что о проблемах с std::async, У меня есть два вопроса:

  1. Для младшего разработчика, есть ли набор правил, что делать и чего избегать при использовании std::async?

  2. Какие проблемы представлены в этом видео? Они связаны с Эта статья?

17

Решение

Есть несколько вопросов:

  1. std::async без политики запуска позволяет библиотеке времени выполнения выбирать, запускать ли новый поток или запускать задачу в потоке, который вызвал get() или же wait() на будущее. Как говорит Херб, это тот случай, который вы, скорее всего, захотите использовать. Проблема в том, что это оставляет его открытым для QoI библиотеки времени выполнения, чтобы правильно определить количество потоков, и вы не знаете, будет ли задача иметь поток для себя, поэтому использование локальных переменных потока может быть проблематичным. Это то, что беспокоит Скотта, насколько я понимаю.

  2. Используя политику std::launch::deferred на самом деле не запускает задачу, пока вы явно не позвоните get() или же wait(), Это почти никогда не то, что вы хотите, так что не делайте этого.

  3. Используя политику std::launch::async начинает новую тему Если вы не отслеживаете количество потоков, это может привести к слишком большому количеству запущенных потоков.

  4. Херб обеспокоен поведением std::future деструктор, который должен ждать завершения задачи, хотя MSVC2012 имеет ошибку в том, что он не ждет.

Для младшего разработчика я бы предложил:

  • использование std::async с политикой запуска по умолчанию.
  • Убедитесь, что вы явно ждете всех своих будущих.
  • Не используйте локальное хранилище в асинхронных задачах.
22

Другие решения

Я не мог не согласиться с советами использовать политику по умолчанию.

Если вы испытываете трудности при разработке независимых вычислительных блоков, вы, вероятно, не ожидаете, что они будут работать последовательно, в то время как полдюжины процессоров крутят свои пальцы, что может «законно» произойти в зависимости от выбранного вами компилятора.

Неявное предположение о поведении по умолчанию заключается в том, что какой-то сложный механизм пула потоков оптимизирует размещение задач (возможно, позволяя некоторым из них запускаться последовательно на ЦП вызывающего), но это чистая фантазия, поскольку ничто не указывает, что должна делать среда выполнения C ++ (что может быть в любом случае выходит за рамки компиляции).

Для меня это больше похоже на неопределенное поведение.

Класс с именем «async» должен запускать асинхронные исполнительные блоки, если какой-либо явный и детерминированный параметр поведения не говорит об обратном.

Честно говоря, за исключением цели отладки, я не вижу смысла в launch::deferred, если вы не планируете писать свой собственный псевдо-планировщик, в этом случае вам будет лучше использовать простые потоки.

Так что мой совет будет уточнить launch::async когда вы используете async(говорит компилятору что-то вроде «эй, я хочу асинхронную задачу, но действительно async, ок? «) и не использовать async вообще, если вы просто хотите выполнять задачи последовательно.

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

7

По вопросам рекламы [email protected]