2010-12-22 7 views
13

Estos días estoy leyendo el pdf Designing MT programs. Explica que el usuario DEBE llamar explícitamente al detach() en un objeto de la clase std::thread en C++ 0x antes de que ese objeto se salga del alcance. Si no lo llama, se llamará al std::terminate() y la aplicación morirá.destructores de hilos en C++ 0x vs impulso

Normalmente utilizo boost::thread para enhebrar en C++. Corrígeme si me equivoco pero un objeto boost::thread se separa automáticamente cuando se sale del alcance.

Me parece que el enfoque de impulso sigue un principio de RAII y el estándar no.

¿Sabes si hay alguna razón particular para esto?

Respuesta

16

esto es cierto, y esta elección se explica en N3225 en una nota con respecto a std::thread destructor:

If joinable() continuación terminate(), de lo contrario no hay efectos. [Nota: ya sea implícita o unirse a separar un hilo joinable() en su destructor podría dar lugar a dificultades a la corrección de depuración (para soltar) o rendimiento (para unirse a los insectos) encontrado sólo cuando una excepción es elevada. Por lo tanto, el programador debe asegurarse de que el destructor nunca se ejecute mientras que el hilo sigue siendo que se puede unir. -fin nota]

Al parecer, el comité fue para el menor de los males.


EDITAR acabo de encontrar this interesting paper que explica por qué la redacción inicial:

Si joinable() continuación detach(), de lo contrario no hay efectos.

se cambió para la cita anterior.

+1

¿Por qué no tener un indicador join_on_destruction o detach_on_destruction en el constructor, o alguna otra forma de especificar explícitamente su comportamiento? – Puppy

+0

Hay un artículo interesante [aquí] (http://www.open-std.org/Jtc1/sc22/wg21/docs/papers/2008/n2802.html) – icecrime

+1

Hola IceCrime. Gracias por el papel. Así que, básicamente, matar la aplicación es la forma más evidente de mostrar una bandera sobre errores en los hilos ... una manera interesante y realmente "defensiva", diría yo. :) –

3

Aquí hay una manera de implementar subprocesos RAII.

#include <memory> 
#include <thread> 

void run() { /* thread runs here */ } 

struct ThreadGuard 
{ 
    operator()(std::thread* thread) const 
    { 
     if (thread->joinable()) 
      thread->join(); // this is safe, but it blocks when scoped_thread goes out of scope 
     //thread->detach(); // this is unsafe, check twice you know what you are doing 
     delete thread; 
    } 
} 

auto scoped_thread = std::unique_ptr<std::thread, ThreadGuard>(new std::thread(&run), ThreadGuard()); 

Si desea usar esto para separar un hilo, read this first.