A juzgar por los simples argumentos de std::async
, parece que no hay forma de controlar la asignación del std::promise
interno y, por lo tanto, puede simplemente usar cualquier cosa, aunque probablemente std::allocator
. Aunque supongo que en teoría no se especifica, es probable que el estado compartido se asigne dentro del hilo de llamada. No he encontrado ninguna información explícita en el estándar sobre este asunto. Al final, std::async
es una función muy especializada para una invocación asíncrona fácil, por lo que no tiene que pensar si realmente es a std::promise
en cualquier lugar.
Para obtener un control más directo sobre el comportamiento de una llamada asíncrona, también existe std::packaged_task
, que de hecho tiene un argumento de asignación. Pero a partir de la mera cita estándar no está perfectamente claro si este asignador solo se usa para asignar almacenamiento para la función (ya que std::packaged_task
es un tipo especial std::function
) o si también se usa para asignar el estado compartido del std::promise
interno, aunque parece probable:
30.6.9.1 [futures.task.members]:
Efectos: construye un nuevo packaged_task
objeto con un estado compartido y inicializa tarea almacenada en el objeto con std::forward<F>(f)
. Los constructores que toman un argumento Allocator
lo usan para asignar la memoria necesaria para almacenar las estructuras internas de datos.
Bueno, ni siquiera decir que no es un std::promise
debajo (lo mismo para std::async
), podría ser sólo un tipo indefinido puede conectar a una std::future
.
Por lo tanto, si de hecho no se especifica cómo std::packaged_task
asigna su estado interno compartido, su mejor opción podría ser implementar sus propias instalaciones para la invocación de funciones asincrónicas. Teniendo en cuenta que, simplemente hablado, un std::packaged_task
es solo un std::function
incluido con un std::promise
y std::async
acaba de iniciar un std::packaged_task
en un nuevo hilo (bueno, excepto cuando no lo hace), esto no debería ser un gran problema.
Pero de hecho esto podría ser un descuido en la especificación. Mientras que el control de asignación realmente no se ajusta al std::async
, la explicación de std::packaged_task
y su uso de asignadores podría ser un poco más clara. Pero esto también puede ser intencional, por lo que el std::packaged_task
es libre de usar lo que quiera y ni siquiera necesita un std::promise
internamente.
EDIT: lectura de nuevo, creo que la cotización estándar por encima de hecho dice, que los std::packaged_task
's estado compartido se asignado usando el asignador proporcionado, ya que es parte de los 'estructuras de datos internas' , cualquiera que sean (sin embargo, no es necesario que sea realmente std::promise
). Así que creo que std::packaged_task
debería ser suficiente para tener un control explícito del estado compartido de una tarea asíncrona std::future
.
¿Dónde se garantiza que el subproceso de llamada asigna el almacenamiento? Ok, es bastante probable, pero aún me gustaría ver una cita del estándar. –
Respuesta actualizada con más detalles. –
De hecho, parece bastante claro, pasé por alto eso. Pero señalar esto en su respuesta como lo hace ahora no puede hacer ningún daño. Gracias y +1. –