2010-05-16 24 views
11

我讀這樣的:http://en.wikipedia.org/wiki/Thread_safety線程安全與堆分配的內存

是下面的函數是線程安全的?

void foo(int y){ 
    int * x = new int[50]; 
    /*...do some stuff with the allocated memory...*/ 
    delete [] x; 
} 

在文章中說它是線程安全的,你只能使用堆棧中的變量。真?爲什麼?上述函數的後續調用不會在其他地方分配內存嗎?

編輯:嗯。貌似我誤讀了文章的這一部分:

子程序是可重入的,因此線程安全的,如果

  • 它使用的唯一變量是從堆棧

(我認爲它的意思是

子例程是可重入的,因此線程安全,如果個且僅當

  • 它使用的唯一變量是從堆棧

,其根據下面的答案,情況並非如此)

+9

使用'delete []'不是'delete'的數組# – 2010-05-17 00:01:41

+0

@Brian:Woops - 謝謝。在我已經輸入了函數之後,我添加了數組部分,以便更清楚地說明我動態分配內存,但忘記添加[]。 +1 :) – Cam 2010-05-17 00:03:44

+1

看到維基百科的傳播使用作爲編程概念的參考,令人驚訝:) – ch0kee 2013-07-31 18:43:48

回答

10

如果您在支持多線程的環境中編碼,那麼你可以很確定new是線程安全的。

雖然存儲器是在堆上,指針到它是在堆棧中。只有你的線程具有指向此內存,因此不存在併發修改的風險 - 沒有其他線程知道哪裏內存進行修改。

,如果你是這個指針傳遞給另一個線程然後將同時在同一時間爲原來的(或其他)的線程修改該內存只能取得與線程安全問題。

+0

謝謝。你的答案和彼得之間的選擇很艱難,但是最後你的有用提示是相關的,而他是關於矢量的:) – Cam 2010-05-17 00:21:12

0

新和刪除可能會或可能不是線程安全的。他們可能是,但這是依賴於實現的。請參閱: C++ new operator thread safety in linux and gcc 4

爲了線程安全,函數必須使用堆棧變量或將其對其他線程的訪問同步到其他資源。只要新的獨立的呼叫從不同的線程調用時在堆上分配不同的空間,你應該罰款。

2

這並不是說你只能使用堆棧變量,它說,使用堆變量「表明需要仔細檢查,看它是否是不安全的」。

newdelete通常以線程安全方式實現(不確定標準是否可以保證),所以上面的代碼可能沒問題。

加上使用std::vector,而不是手動分配的陣列通常建議,但我認爲你只提供作爲一個例子:)

+1

我記得在一個他們不是的環境中工作。現在*那*很毛茸茸。 – Joshua 2010-05-17 00:48:51

+1

很幸運,你可以重寫他們:) – 2010-05-17 12:55:32