2017-10-18 136 views
1
for (int i = 0; i < 10; i++) { 
    thread *t = new thread(example_function); 
    t->join(); 
} 

我在做我的編碼項目類似的東西,想知道是否因爲線程都在循環中定義它們在循環結束後銷燬後(我摧毀知道線程指針可能會被刪除,但線程本身呢?)。C++ - 是這些線程的for循環完成

+1

通常當你使用新的,你分配內存,你需要使用刪除來刪除它或內存區域將保持分配,直到程序結束 –

+3

@TemaniAfif你可能是指'刪除'。 – Ron

+1

@Ron yes!免費與malloc,只是一個錯誤... –

回答

4

不,threadfor循環內創建的對象不會被銷燬,這意味着它們會產生內存泄漏。

爲了確保線程被破壞,你需要在幾種方法之一調用delete他們:

  • 呼叫delete在範圍的結束,或
  • 添加線程指針一個指針的容器,並且在一個單獨的循環中調用delete,或者
  • 將線程指針添加到智能指針,以確保範圍結束時刪除,或者將線程指針添加到智能指針容器中,並讓容器在超出作用域時刪除線程。

請注意,由於您在每次循環迭代中調用join,因此「併發」程序與單線程程序一樣好。以下是如何同時運行的線程,並確保螺紋缺失底:

std::vector<std::unique_ptr<std::thread>>> threads; 
for (int i = 0; i < 10; i++) { 
    threads.push_back(std::make_unique<thread>(example_function)); 
} 
for (int i = 0; i < 10; i++) { 
    threads[i]->join(); 
} 

一旦threads矢量超出範圍時,它會刪除它裏面std::unique_ptr<thread>對象,這反過來又呼籲各std::thread對象delete

+1

@ user3572917是的,因爲你不立即等待你剛剛開始的線程。你創建它們,然後開始等待每一個。 – luk32

+0

'make_unique'裏面不需要'new'(並不是說整個動態分配是不必要的) – Slava

+0

@Slava你說得對,他們將參數轉發給實際的'new'。謝謝!啊,你在這個例子中沒有必要進行動態分配是正確的。 – dasblinkenlight

0

這裏

thread *t = new thread(example_function); 

你已經失去了以前分配thread實例,並有內存泄漏。

join()不釋放分配的內存,但拾取異步結束的函數。

2

我在做我的編碼項目類似的東西,如果因爲線程得到他們在循環後銷燬內循環定義結束使用運營商new動態分配的

整個目的是想知道是提供手動控制對象的生命週期。因此,不,直到你明確地調用delete或者你使用了一個智能指針,它在你的引擎蓋下,你的對象不會被銷燬。請注意,在循環內部有效地調用std::thread::join()會使您的程序單線程化。更正確的使用將是:new

std::vector<std::thread> threads; 
while(threads.size() < 10) 
    threads.emplace_back(example_function); 

for(auto &thread : threads) 
    thread.join(); // join in a separate loop, let all threads to start 

threads.clear(); // or let it go out of scope 
+0

我在想同樣的事情,除了把代碼放在'{}'中做一個併發執行的範圍。 – luk32

0

號調用者有責任確保使用分配對象是delete d。

的代碼當然是很沒有意義的,因爲沒有有意義的併發出現,但爲了避免內存泄漏應該是:

for (int i = 0; i < 10; i++) { 
    thread *t = new thread(example_function); 
    t->join(); 
    delete t; 
} 

在C++ 11日起的任何版本,建議您在這些情況下使用std::unique_ptr

最推薦的形式是:

auto t{std::make_unique<std::thread>(example_function)}; 

這幾乎等同於:

std::unique_ptr<std::thread> t(new std::thread(example_function)); 

一個std::unique_ptr是具有運算符重載表現很像與刪除東西的差別的指針指向一個對象(如果有的話)在其壽命時結束。