usar threads thread libreria library ejemplos ejemplo c++ multithreading c++11 stdthread

threads - C++ 11: std:: thread mancomunado?



threads c++> (4)

En C ++ 03 utilicé pthread con un grupo de subprocesos autoconstruido que siempre mantenía un par de subprocesos en ejecución (ya que pthread_create es lento), de esta manera pude iniciar subprocesos para tareas pequeñas sin pensar en problemas de rendimiento.

Ahora, en C ++ 11 tenemos std::thread . Supongo que el estándar no dice nada sobre la implementación específica, por lo que mi pregunta es acerca de las implementaciones estándar de la biblioteca. ¿Están generalmente optando por un enfoque agrupado donde la construcción de std::thread s es barata (y, por ejemplo, no llama a pthread_create en posix), o std::thread solo será un contenedor?

En otras palabras, ¿todavía se recomienda un grupo de subprocesos en C ++ 11, o debería simplemente crear un std::thread cuando lo necesite y dejar el rendimiento en la biblioteca estándar?


En general, std::thread debe ser un contenedor mínimo alrededor de la primitiva del sistema subyacente. Por ejemplo, si está en la plataforma pthread , puede probar con el siguiente programa que, independientemente de la cantidad de subprocesos que cree, todos están creados con pthread únicos (lo que implica que se crean sobre la marcha y no se toman prestados de un grupo de hilos):

#include <assert.h> #include <mutex> #include <set> #include <thread> #include <vector> #include <pthread.h> int main() { std::vector<std::thread> workers; std::set<long long> thread_ids; std::mutex m; const int n = 1024; for (int i = 0; i < n; ++i) { workers.push_back(std::thread([&] { std::lock_guard<std::mutex> lock(m); thread_ids.insert(pthread_self()); })); } for (auto& worker : workers) { worker.join(); } assert(thread_ids.size() == n); return 0; }

Así que los grupos de subprocesos siguen teniendo perfecto sentido. Dicho esto, he visto un video en el que los miembros del comité de C ++ discutían los grupos de hilos con respecto a std::async (IIRC), pero no puedo encontrarlo ahora.


Primero, como mencionaste, el estándar C ++ básicamente no especifica la implementación de la biblioteca. Pero un implementador de la biblioteca estándar de C ++ obedecerá la regla "como si".

Por ejemplo, significa que el constructor de std::thread se comportará como si se creara un nuevo hilo, ya sea un envoltorio delgado de la API subyacente o una implementación eficiente, como el grupo de subprocesos. (aquí, ''hilo'' significa un hilo abstracto de ejecución en la especificación C ++ 11, no un hilo concreto nativo del sistema operativo)

En la implementación de grupo de hilos;

  • El compilador y la biblioteca de C ++ deben tratar adecuadamente los recursos específicos de subprocesamiento de C ++ (es decir, la variable thread_local ), y deben funcionar juntos de forma cooperativa en el tiempo de ejecución.
  • Incluso si se cumplió la condición anterior, parece imposible trabajar en conjunto con los recursos de subproceso específicos del sistema operativo (TLS para Windows, TSS para pthread, etc.).

Por lo tanto, supongo que la mayoría de la implementación de std::thread es solo un contenedor de la API de threading subyacente.


Un std::thread es un hilo de ejecución. Período. De dónde viene, cómo llega allí, si hay algún grupo de hilos "actuales", etc., es irrelevante para el estándar. Siempre que actúe como un hilo, podría ser un std::thread .

Ahora, las probabilidades son buenas de que std::thread sea ​​un hilo del sistema operativo de la vida real, no algo extraído de un grupo de subprocesos o lo que sea. Pero C ++ 11 teóricamente permite que un std::thread se implemente como algo extraído de un pool.


std::thread se supone que es muy barato en términos de costos de abstracción, es algo de bajo nivel. Tal como lo entiendo, las implementaciones estándar de la biblioteca probablemente solo envolverán los mecanismos subyacentes del sistema operativo lo más cerca posible para que pueda asumir que la sobrecarga de la creación del hilo sea similar o equivalente.

No conozco ninguna implementación específica, pero mi comprensión de segunda mano al leer C ++ Concurrency In Action es que el estándar sugiere que utilizan el método más eficiente y práctico. El autor ciertamente parecía pensar que el costo sería más o menos insignificante en comparación con el bricolaje.

La biblioteca es similar a Boost conceptualmente, así que me imagino que usar la implementación de Boost para sacar algunas conclusiones no sería demasiado descabellado.

Básicamente, no creo que haya una respuesta para su pregunta directamente porque simplemente no está especificada. Aunque me parece que es más probable que veamos implementaciones de envoltura muy delgadas, no creo que a los escritores de librerías se les restrinja el uso de grupos de subprocesos si ofrece beneficios de eficiencia.