2012-05-19 16 views
13

Quiero aprender a crear múltiples hilos con la nueva biblioteca estándar de C++ y almacenar sus identificadores en una matriz.
¿Cómo puedo iniciar un hilo?
Los ejemplos que vi iniciaron un hilo con el constructor, pero si uso array, no puedo llamar al constructor.¿Cómo crear una matriz de objetos de hilo en C++ 11?

#include <iostream> 
#include <thread> 

void exec(int n){ 
    std::cout << "thread " << n << std::endl; 
} 

int main(int argc, char* argv[]){ 

    std::thread myThreads[4]; 

    for (int i=0; i<4; i++){ 
     //myThreads[i].start(exec, i); //?? create, start, run 
     //new (&myThreads[i]) std::thread(exec, i); //I tried it and it seems to work, but it looks like a bad design or an anti-pattern. 
    } 
    for (int i=0; i<4; i++){ 
     myThreads[i].join(); 
    } 

} 

Respuesta

35

No es nada especial requerido; solo usa la asignación. Dentro de su bucle, escriba

myThreads[i] = std::thread(exec, i); 

y debería funcionar.

+0

Pero creará un objeto temporal, llamará a un constructor, realizará una asignación y luego llamará al destructor. El estado puede ser inconsistente. Lo intenté y está funcionando, pero no sé si funcionará alguna vez. – Squall

+13

Funciona usando la semántica de movimiento. Nada será inconsistente, funciona por diseño. La propiedad del nuevo hilo de ejecución se transferirá del elemento temporal al elemento de matriz, dejando el temporal en el mismo estado que un objeto de subproceso construido por defecto, es decir, que no se refiere a ningún hilo de ejecución, por lo que se puede destruir de forma segura. –

-4

Con C++ 0x/C++ 11, intente utilizar vectores en lugar de matrices de hilos; algo como esto:

vector<thread> mythreads; 
int i = 0; 
for (i = 0; i < 8; i++) 
{ 
    mythreads.push_back(dostuff, withstuff); 
} 
auto originalthread = mythreads.begin(); 
//Do other stuff here. 
while (originalthread != mythreads.end()) 
{ 
    originalthread->join(); 
    originalthread++; 
} 

Editar: Si realmente quiere manejar la asignación de memoria sí mismo y utilizar una matriz de punteros (es decir, vectores simplemente no es lo suyo), entonces no puedo recomendar lo suficiente valgrind. Tiene inspectores de asignación de memoria y comprobadores de hilo, etc., etc. No tiene precio para este tipo de cosas. En cualquier caso, aquí está un programa de ejemplo utilizando una gran variedad de temas asignados manualmente, y se limpia después de sí mismo (no hay pérdidas de memoria):

#include <iostream> 
#include <thread> 
#include <mutex> 
#include <cstdlib> 

// globals are bad, ok? 
std::mutex mymutex; 


int pfunc() 
{ 
    int * i = new int; 
    *i = std::rand() % 10 + 1; 

    // cout is a stream and threads will jumble together as they actually can 
    // all output at the same time. So we'll just lock to access a shared 
    // resource. 
    std::thread::id * myid = new std::thread::id; 
    *myid = std::this_thread::get_id(); 
    mymutex.lock(); 
    std::cout << "Hi.\n"; 
    std::cout << "I'm threadID " << *myid << std::endl; 
    std::cout << "i is " << *i << ".\n"; 
    std::cout << "Bye now.\n"; 
    mymutex.unlock(); 

    // Now we'll sleep in the thread, then return. 
    sleep(*i); 
    // clean up after ourselves. 
    delete i; 
    delete myid; 
    return(0); 
} 


int main() 
{ 

    std::thread * threadpointer = new std::thread[4]; 
    // This seed will give us 5, 6, 4, and 8 second sleeps... 
    std::srand(11); 
    for (int i = 0; i < 4; i++) 
    { 
     threadpointer[i] = std::thread(pfunc); 
    } 
    for (int i = 0; i < 4; i++) 
     // Join will block our main thread, and so the program won't exit until 
     // everyone comes home. 
    { 
     threadpointer[i].join(); 
    } 
    delete [] threadpointer; 
} 
+1

@Nevin (Como no puedo comentar las respuestas de nadie más) ¿ha intentado ejecutar su solución a través de valgrind --tool = helgrind? Estoy en GCC 4.5.2 y, a partir de la salida, veo que parece que hacer threads como los que muestra realmente se adentra en un territorio de comportamiento indefinido con C++ 11 threads. – Kionmaru

+6

No es necesario usar 'new' /' delete' tanto. –

+1

Kionmaru, ver http://stackoverflow.com/a/10624266/981959 antes de usar helgrind con std :: thread. –

Cuestiones relacionadas