2012-05-19 22 views
13

Voglio imparare come creare più thread con la nuova libreria standard C++ e archiviare i loro handle in una matrice.
Come posso iniziare una discussione?
Gli esempi che ho visto avviano un thread con il costruttore, ma se uso array, non posso chiamare il costruttore.Come creare una matrice di oggetti thread in 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(); 
    } 

} 

risposta

35

Niente di speciale richiesto; usa il compito. All'interno del tuo ciclo, scrivi

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

e dovrebbe funzionare.

+0

Ma creerà un oggetto temporaneo, chiamerà un costruttore, eseguirà un assegnamento e chiamerà il distruttore. Lo stato potrebbe essere incoerente. L'ho provato e funziona, ma non so se funzionerà mai. – Squall

+13

Funziona usando la semantica del movimento. Niente sarà incoerente, funziona in base alla progettazione. La proprietà del nuovo thread di esecuzione verrà trasferita dall'elemento temporaneo all'array, lasciando il temporaneo nello stesso stato di un oggetto thread predefinito, vale a dire senza riferimento a nessun thread di esecuzione, in modo che possa essere distrutto in modo sicuro. –

-4

Con C++ 0x/C++ 11, prova usando vettori invece di array di fili; qualcosa di simile:

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++; 
} 

Edit: Se davvero si vuole gestire l'allocazione di memoria da soli e utilizzare un array di puntatori (vale a dire i vettori semplicemente non sono la vostra passione), allora non posso raccomandare valgrind vivamente. Ha controller di allocazione della memoria e controller di thread, ecc. Ecc. Priceless per questo genere di cose. In ogni caso, ecco un esempio di programma utilizzando una matrice di thread allocati manualmente e pulisce dopo stessa (nessuna perdita di 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 (Dal momento che non posso commentare le risposte di nessun altro) hai provato a eseguire la soluzione tramite valgrind --tool = helgrind? Sono su GCC 4.5.2 e dall'output vedo che sembra che thread come quelli che stai mostrando entrino effettivamente in un territorio di comportamento non definito con thread C++ 11. – Kionmaru

+6

Non c'è bisogno di usare 'new' /' delete' tanto. –

+1

Kionmaru, consultare http://stackoverflow.com/a/10624266/981959 prima di utilizzare helgrind con std :: thread. –

Problemi correlati