В начале этот клип из C ++ и далее, я слышал кое-что о проблемах с std::async
, У меня есть два вопроса:
Для младшего разработчика, есть ли набор правил, что делать и чего избегать при использовании std::async
?
Какие проблемы представлены в этом видео? Они связаны с Эта статья?
Есть несколько вопросов:
std::async
без политики запуска позволяет библиотеке времени выполнения выбирать, запускать ли новый поток или запускать задачу в потоке, который вызвал get()
или же wait()
на будущее. Как говорит Херб, это тот случай, который вы, скорее всего, захотите использовать. Проблема в том, что это оставляет его открытым для QoI библиотеки времени выполнения, чтобы правильно определить количество потоков, и вы не знаете, будет ли задача иметь поток для себя, поэтому использование локальных переменных потока может быть проблематичным. Это то, что беспокоит Скотта, насколько я понимаю.
Используя политику std::launch::deferred
на самом деле не запускает задачу, пока вы явно не позвоните get()
или же wait()
, Это почти никогда не то, что вы хотите, так что не делайте этого.
Используя политику std::launch::async
начинает новую тему Если вы не отслеживаете количество потоков, это может привести к слишком большому количеству запущенных потоков.
Херб обеспокоен поведением std::future
деструктор, который должен ждать завершения задачи, хотя MSVC2012 имеет ошибку в том, что он не ждет.
Для младшего разработчика я бы предложил:
std::async
с политикой запуска по умолчанию.Я не мог не согласиться с советами использовать политику по умолчанию.
Если вы испытываете трудности при разработке независимых вычислительных блоков, вы, вероятно, не ожидаете, что они будут работать последовательно, в то время как полдюжины процессоров крутят свои пальцы, что может «законно» произойти в зависимости от выбранного вами компилятора.
Неявное предположение о поведении по умолчанию заключается в том, что какой-то сложный механизм пула потоков оптимизирует размещение задач (возможно, позволяя некоторым из них запускаться последовательно на ЦП вызывающего), но это чистая фантазия, поскольку ничто не указывает, что должна делать среда выполнения C ++ (что может быть в любом случае выходит за рамки компиляции).
Для меня это больше похоже на неопределенное поведение.
Класс с именем «async» должен запускать асинхронные исполнительные блоки, если какой-либо явный и детерминированный параметр поведения не говорит об обратном.
Честно говоря, за исключением цели отладки, я не вижу смысла в launch::deferred
, если вы не планируете писать свой собственный псевдо-планировщик, в этом случае вам будет лучше использовать простые потоки.
Так что мой совет будет уточнить launch::async
когда вы используете async
(говорит компилятору что-то вроде «эй, я хочу асинхронную задачу, но действительно async, ок? «) и не использовать async
вообще, если вы просто хотите выполнять задачи последовательно.
Если у вас возникли проблемы с асинхронными задачами, может быть удобно вернуться к deferred
политика их отладки проще, но это все.