Как функция может запускаться «как будто» в новом потоке без этого? - PullRequest
0 голосов
/ 07 мая 2018

В соответствии с [futures.async] / 3 bullet 1 стандарта C ++, когда функция f передается в std::async с политикой запуска std::launch::async, f будет запускаться «как в новом потоке» исполнения ".

Учитывая, что f может делать что угодно, включая бесконечный цикл и вечный блок, как реализация может предложить поведение f, работающее в своем собственном потоке, без фактического запуска в своем собственном потоке? То есть, как реализация может использовать «простор для маневра», которую предоставляет Стандарт?

Ответы [ 7 ]

0 голосов
/ 24 мая 2018

Единственное решение без Thread, которое я могу себе представить, - это вчерашняя функция Time-Slicing, которая является формой многозадачности. Функции должны быть повторно введены. В таком случае каждая функция будет работать так, как будто они находятся в разных потоках, хотя практически они находятся в одном потоке.

0 голосов
/ 24 мая 2018

В документах там указано,

Функция шаблона async запускает функцию f асинхронно (возможно, в отдельном потоке, который может быть частью пула потоков) и возвращает std :: future, который в конечном итоге будет содержать результат вызова этой функции ,

http://en.cppreference.com/w/cpp/thread/async

0 голосов
/ 24 мая 2018

Я вижу основную идею "f будет работать", как будто в новом потоке выполнения "" заключается в том, что f будет работать асинхронно. Должен ли это быть новый поток или что-то еще, это детали реализации.

0 голосов
/ 24 мая 2018

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

std::thread::hardware_concurrency();

Вы получите:

Возвращает количество одновременных потоков, поддерживаемых осуществление.

Допустим, у вас результат равен 4. Вы хотите выполнить обновление многих вещей параллельно. Основной поток отслеживает список фьючерсов (3 слева) и время от времени проверяет, выполнено это или нет, и если выполнено, выполните следующую операцию из списка задач. Прибыль здесь, например, если вы обновляете другой тип памяти, такой как 1-FileSystem, 2-EEPROM, 3-NOR память или что-то в этом роде. Нет никакой выгоды от проверки в цикле без задержки, поэтому вы хотите дать задание 4-му потоку между проверками. Вы пишете функцию, которая копает биткойны за 50 миллисекунд :) и вы запускаете его как отложенный между проверками.

А потом, как вы упомянули, у нас есть:

преимущество "как будто" комнаты для маневра в стандарте

0 голосов
/ 23 мая 2018

Если посмотреть на ссылки на C ++, которые отображаются здесь и здесь , то кажется , что цель "как будто" состоит в том, чтобы позволить реализации библиотеки некоторой степени свобода. Например, написано

как будто порождено std :: thread (std :: forward (f), std :: forward (args) ...), за исключением того, что если функция f возвращает значение или выбрасывает исключение, оно хранится в общем состоянии доступный через std :: future, который async возвращает вызывающей стороне.

в первом источнике и

как будто объект потока создается с аргументами fn и args, и доступ к общему состоянию возвращенного будущего присоединяется к нему

во втором. Таким образом, похоже, что поведение похоже на std::thread, но может быть реализовано по-другому. Это интересно, поскольку фраза нить исполнения , которую вы цитируете здесь, отличается от std::thread. Тем не менее, кажется, что оба источника понимают как-будто таким образом.

Другой вариант может быть, как предложено Франсуа Андрие , разрешить использование пула потоков, как указано в первом источнике:

Функция шаблона async выполняет функцию f асинхронно (потенциально в отдельном потоке, который может быть частью пула потоков)

0 голосов
/ 21 мая 2018

AFAIK среда выполнения C ++ способна управлять некоторыми внутренними (или специализированными) потоками, отличающимися от стандартных потоков.

Мне кажется (я все еще изучаю расширенные возможности C ++), что с флагом std::launch::async std::async() запустит f в новом внутреннем потоке.

Вы можете запустить f в новом стандартном потоке , используя std::thread. В этом случае исключения будут обрабатываться в вызываемом потоке, и основной код должен будет получить возвращаемое значение f.

С внутренним потоком возвращаемое значение и возможное исключение сохраняются в std::future, возвращаются std::async() и распределяются между потоками.

Так что «как будто» означает «как будто я запускаю f с std::thread, но мне не нужно». Но наверняка f будет запущен в новом потоке.

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

0 голосов
/ 07 мая 2018

Некоторые способы, которыми я могу думать о том, что f может работать «как если бы» в новом потоке, фактически не делая этого, были бы, если бы f фактически не использовал никакого состояния, совместно используемого с другими потоками; затем реализация может запустить его как отдельный процесс (так как ему не нужно пространство общей памяти), она также может просто запустить его в основном потоке как просто еще один вызов функции (если она может доказать, что f не блокирует или имеют наблюдаемые побочные эффекты, которые будут отличаться при запуске таким образом). Он также может быть запланирован для запуска в существующем (но бездействующем) потоке (пуле потоков).

И если вы хотите быть глупым, я думаю, вы могли бы также подумать о том, чтобы вообще не запускать f , поскольку нет никаких гарантий относительно того, когда новые потоки будут запланированы для запуска операционная система, поэтому злая реализация может просто сказать, что ОС никогда не планирует какой-либо поток, кроме основного потока, поэтому полное отсутствие f равносильно планированию его в новом потоке. Конечно, это глупо / глупо, и никакая вменяемая реализация никогда бы этого не сделала - но в теории 1011 * язык допускает такую ​​вырожденную реализацию (я думаю).

...