Судя только по аргументам std::async
, кажется, что нет никакого способа контролировать распределение внутреннего std::promise
, и поэтому он может просто использовать что угодно, хотя, вероятно, std::allocator
. Хотя я предполагаю, что теоретически это не указано, вполне вероятно, что общее состояние выделяется внутри вызывающего потока. Я не нашел никакой явной информации в стандарте по этому вопросу. В конце концов, std::async
— это очень специализированное средство для простого асинхронного вызова, так что вам не нужно думать, есть ли вообще где-нибудь есть std::promise
.
Для более прямого управления поведением асинхронного вызова также есть std::packaged_task
, который действительно имеет аргумент распределителя. Но из простой стандартной цитаты не совсем ясно, используется ли этот распределитель только для выделения памяти для функции (поскольку std::packaged_task
является своего рода специальным std::function
) или он также используется для выделения общего состояния внутреннего std::promise
, хотя кажется вероятным:
30.6.9.1 [futures.task.members]:
Эффекты: создает новый объект packaged_task
с общим состоянием и инициализирует сохраненную задачу объекта с помощью std::forward<F>(f)
. Конструкторы, принимающие аргумент Allocator
, используют его для выделения памяти, необходимой для хранения внутренних структур данных.
Ну, это даже не говорит, что внизу есть std::promise
(аналогично для std::async
), это может быть просто неопределенный тип, который можно подключить к std::future
.
Поэтому, если действительно не указано, как std::packaged_task
распределяет свое внутреннее общее состояние, лучше всего реализовать собственные средства для асинхронного вызова функций. Учитывая, что, говоря простым языком, std::packaged_task
— это просто std::function
в комплекте с std::promise
, а std::async
просто запускает std::packaged_task
в новом потоке (ну, за исключением случаев, когда это не так), это не должно быть большой проблемой.
Но на самом деле это может быть оплошностью в спецификации. В то время как управление распределением не очень подходит для std::async
, объяснение std::packaged_task
и его использования распределителей может быть немного яснее. Но это также может быть преднамеренным, поэтому std::packaged_task
может использовать все, что захочет, и даже не нуждается в std::promise
внутри.
EDIT: Читая это снова, я думаю, что приведенная выше стандартная цитата действительно говорит о том, что общее состояние std::packaged_task
выделяется с использованием предоставленного распределителя, поскольку оно является частью "внутренние структуры данных", что бы это ни было (хотя std::promise
не обязательно). Поэтому я думаю, что std::packaged_task
должно быть достаточно для явного управления общим состоянием std::future
асинхронной задачи.
person
Christian Rau
schedule
11.10.2012