2012-05-19 42 views
13

我想學習如何用新的C++標準庫創建多個線程並將它們的句柄存儲到一個數組中。
如何啓動線程?
我看到的例子用構造函數啓動線程,但如果我使用數組,我無法調用構造函數。如何在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(); 
    } 

} 

回答

35

沒什麼特別;只是使用任務。在你的循環內,寫入

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

它應該工作。

+0

但它會創建一個臨時對象,調用構造函數,執行賦值,然後調用析構函數。國家可能不一致。我試過了,它正在工作,但我不知道它是否會工作。 – Squall

+13

它使用移動語義。沒有什麼會不一致,它通過設計起作用。新執行線程的所有權將從臨時數據庫傳遞到數組元素,使臨時數據與默認構造的線程對象處於相同狀態,即不引用任何執行線程,因此可以安全銷燬它。 –

-4

用C++ 0x/C++ 11,嘗試使用矢量而不是線程數組;是這樣的:

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

編輯:如果你真的想自己處理內存的分配和使用指針數組(即向量只是是不是你的東西),那麼我可以不推薦Valgrind的高度不夠。它有內存分配檢查器和線程檢查器等等,對於這種事情是無價的。在任何情況下,這裏的使用手動分配的線程的陣列的示例性程序,並且它本身後清理(無內存泄漏):所需

#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(因爲我不能評論任何人的答案)您是否嘗試過通過valgrind --tool = helgrind運行您的解決方案?我在GCC 4.5.2上,從輸出中看到它看起來像你所顯示的線程實際上是通過C++ 11線程進入未定義的行爲區域。 – Kionmaru

+6

沒有必要這麼用'new' /'delete'。 –

+1

Kionmaru,在使用helgrind和std :: thread之前,請參閱http://stackoverflow.com/a/10624266/981959。 –