¿Async (launch :: async) en C ++ 11 hace que los grupos de subprocesos se vuelvan obsoletos para evitar la creación de subprocesos costosos?

Está vagamente relacionado con esta pregunta:¿Está std :: thread agrupado en C ++ 11?. Aunque la pregunta difiere, la intención es la misma:

Pregunta 1: ¿Todavía tiene sentido utilizar sus propios grupos de subprocesos (o la biblioteca de terceros) para evitar la creación de subprocesos costosos?

La conclusión en la otra pregunta fue que no se puede confiar enstd::thread para ser agrupados (puede o no puede ser). Sin embargo,std::async(launch::async) Parece tener una oportunidad mucho mayor de ser agrupados.

No creo que esté forzado por el estándar, pero, en mi humilde opinión, yo esperaría que todas las buenas implementaciones de C ++ 11 usarían la agrupación de subprocesos si la creación de subprocesos fuera lenta. Solo en las plataformas donde es barato crear un nuevo hilo, espero que siempre generen un nuevo hilo.

Pregunta 2: Esto es justo lo que pienso, pero no tengo datos que lo demuestren. Puede que me equivoque. ¿Es una conjetura educada?

Finalmente, aquí proporcioné algunos ejemplos de código que muestran primero cómo creo que la creación de hilos se puede expresar medianteasync(launch::async):

Ejemplo 1:

 thread t([]{ f(); });
 // ...
 t.join();

se convierte en

 auto future = async(launch::async, []{ f(); });
 // ...
 future.wait();

Ejemplo 2: Encender y olvidar hilo.

 thread([]{ f(); }).detach();

se convierte en

 // a bit clumsy...
 auto dummy = async(launch::async, []{ f(); });

 // ... but I hope soon it can be simplified to
 async(launch::async, []{ f(); });

Pregunta 3: ¿Prefieres elasync versiones para elthread versiones?

El resto ya no es parte de la pregunta, sino solo para aclarar:

¿Por qué debe asignarse el valor de retorno a una variable ficticia?

Desafortunadamente, el estándar actual de C ++ 11 obliga a capturar el valor de retorno destd::async, de lo contrario se ejecuta el destructor, que bloquea hasta que la acción termina. Es considerado por algunos como un error en el estándar (por ejemplo, por Herb Sutter).

Este ejemplo decppreference.com lo ilustra muy bien:

{
  std::async(std::launch::async, []{ f(); });
  std::async(std::launch::async, []{ g(); });  // does not run until f() completes
}

Otra aclaración:

Yo sé esolos grupos de subprocesos pueden tener otros usos legítimos, pero en esta pregunta solo me interesa el aspecto de evitar costosos costos de creación de subprocesos.

Creo que todavía hay situaciones en las que los grupos de subprocesos son muy útiles, especialmente si necesita más control sobre los recursos. Por ejemplo, un servidor puede decidir manejar solo un número fijo de solicitudes simultáneamente para garantizar tiempos de respuesta rápidos y para aumentar la previsibilidad del uso de la memoria. Las piscinas de hilo deberían estar bien, aquí.

Las variables de subprocesos locales también pueden ser un argumento para sus propios grupos de subprocesos, pero no estoy seguro de que sea relevante en la práctica:

Creando un nuevo hilo constd::thread se inicia sin inicializar variables de subproceso local. Tal vez esto no es lo que quieres.En hilos generados porasync, no está claro para mí porque el hilo podría haberse reutilizado. A mi entender, las variables de subprocesos locales no están garantizadas para restablecerse, pero puedo estar equivocado.El uso de sus propios grupos de subprocesos (de tamaño fijo), por otro lado, le da control total si realmente lo necesita.

Respuestas a la pregunta(1)

Su respuesta a la pregunta