2012-05-19 18 views
13

Chcę nauczyć się tworzyć wiele wątków za pomocą nowej standardowej biblioteki C++ i przechowywać ich uchwyty w tablicy.
Jak mogę uruchomić wątek?
Przykłady, które widziałem, uruchamiają wątek z konstruktorem, ale jeśli używam tablicy, nie mogę wywołać konstruktora.Jak utworzyć tablicę obiektów wątków w 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(); 
    } 

} 

Odpowiedz

35

Nic nadzwyczajnego wymagane; po prostu użyj zadania. Wewnątrz pętli napisz:

i powinno działać.

+0

Ale utworzy tymczasowy obiekt, wywoła konstruktor, wykona zadanie, a następnie wywoła destruktor. Stan może być niespójny. Próbowałem i działa, ale nie wiem, czy to zadziała. – Squall

+13

Działa za pomocą semantyki ruchu. Nic nie będzie niespójne, działa zgodnie z projektem. Własność nowego wątku wykonania zostanie przeniesiona z elementu tymczasowego do elementu tablicy, pozostawiając tymczasowy w tym samym stanie, co obiekt wątku skonstruowany domyślnie, tj. Nie odnosząc się do żadnego wątku wykonania, aby można go było bezpiecznie zniszczyć. –

-4

Przy C++ 0x/C++ 11, spróbuj użyć wektorów zamiast tablic wątków; coś takiego:

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

Edycja: Jeśli naprawdę chcesz do obsługi alokacji pamięci siebie i wykorzystywać tablicę wskaźników (czyli wektory prostu nie są twoje rzeczy), to nie mogę polecić valgrind bardzo mało. Ma kontrolery alokacji pamięci i kontrolery wątków, itp., Itp. Bezcenne dla tego rodzaju rzeczy. W każdym razie, oto przykładowy program przy użyciu tablicy ręcznie przydzielone wątków, i sprząta po sobie (nie ma wycieków pamięci):

#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 (skoro nie mogę skomentować nikomu odpowiedzi) czy próbowałeś uruchomić swoje rozwiązanie przez valgrind --tool = helgrind? Korzystam z GCC 4.5.2 iz tego, co widzę, wygląda na to, że wątki takie jak pokazywane w rzeczywistości wnikają w obszar nieokreślonego zachowania z wątkami C++ 11. – Kionmaru

+6

Nie ma potrzeby używania "nowych"/"usuń" tak bardzo. –

+1

Kionmaru, patrz http://stackoverflow.com/a/10624266/981959 przed użyciem helgrind ze std :: thread. –

Powiązane problemy