2012-05-19 28 views
13

Yeni C++ standart kitaplığı ile birden çok iş parçacığı oluşturmayı öğrenmek ve tutamaçlarını bir dizide saklamak istiyorum.
Bir iş parçacığı nasıl başlatırım?
Gördüğüm örnekler kurucu ile bir iş parçacığı başlatır, ancak diziyi kullanırsam, yapıcıyı arayamıyorum.C++ 11'de bir dizi konu nesnesi nasıl oluşturulur?

#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(); 
    } 

} 

cevap

35

Hiçbir şey fantezi gerekli;: (hafıza sızıntıları) Her durumda, burada elle tahsis parçacığı bir dizi kullanarak bir örnek program, ve kendisini sonra temizler sadece ödevi kullan. Döngününüzün içinde,

yazıp çalışması gerekir.

+0

Ancak geçici bir nesne oluşturacak, bir yapıcıyı arayacak, ödev yapıp yıkıcıyı arayacaktır. Devlet tutarsız olabilir. Denedim ve çalışıyor, ama işe yarayıp yaramadığını bilmiyorum. – Squall

+13

Hareket semantiği kullanarak çalışır. Hiçbir şey tutarsız olmaz, tasarıma göre çalışır. Yeni icra sırasının mülkiyeti geçici olarak dizi elemanına aktarılır, geçici olarak geçici olarak yapılandırılmış bir iplik nesnesi ile aynı durumda bırakılır, yani herhangi bir icra ipliğine atıfta bulunulmaksızın güvenli bir şekilde imha edilebilir. –

-4

C++ 0x/C++ 11 ile, iş parçacıklarının dizileri yerine vektörleri kullanmayı deneyin; Böyle bir şey:

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

Düzenleme: Eğer gerçekten bellek ayırma kendini idare ve sonra valgrind yeterince tavsiye edemez işaretçiler bir dizi (yani vektörler sadece şey değildir) kullanmak istiyorsanız. Bu bellek tahsisi denetleyicileri ve iş parçacığı denetleyicileri, vb. Vardır. Bu tür şeyler için paha biçilemez.

#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 (Kimsenin cevapları hakkında yorum yapamayacağından), çözümünüzü valgrind --tool = helgrind aracılığıyla çalıştırmayı denediniz mi? GCC 4.5.2 üzerinde çalışıyorum ve gördüğünüz gibi C++ 11 iş parçacığı ile tanımlanamayan davranışsal bölgeye giriyormuş gibi görünmek gibi görünüyor. – Kionmaru

+6

'new' /' delete' kullanmaya gerek yok. –

+1

Kionmaru, std :: thread ile helgrind kullanmadan önce http://stackoverflow.com/a/10624266/981959 adresine bakın. –

İlgili konular