2012-07-23 71 views
4

我有幾個圈,我採用了傳統的語法更改foreach循環到Parallel.ForEach和莫名其妙的錯誤

foreach(x in xs) {....} 

一些環路都在計算方面非常密集,我只是使用並行改變了他們寫道:這樣的語法:

Parallel.ForEach(x, xs => {...}); 

我看到性能的主要增加!現在我的問題是:我使用並行多線程來引入錯誤嗎?我讀到這個線程的安全性很複雜,可能會產生奇怪的錯誤;我應該關注什麼?

+4

如果你只是改變循環而不知道代碼是否是線程安全的,那麼*是的,你應該關心!*代碼將並行運行,所以基本上你不能在並行循環之間共享數據。 – 2012-07-23 16:47:47

+0

@BrianRasmussen:你能告訴我一個不該做什麼的例子嗎? – frenchie 2012-07-23 16:49:49

+0

循環中讀取/寫入共享數據。 – 2012-07-23 16:51:03

回答

3

訪問共享狀態很可能不會產生所需的結果。簡單的例子:

int sum = 0; 
for (int i = 0; i < 1000000; i++) 
{ 
    sum++; 
} 

改變這

Parallel.For(0, 1000000, i => { sum++; }); 

,你會看到sum因爲多線程讀取/寫入sum會有一些隨機值。

如果鎖定更新,您將解決問題,但您將基本上將操作再次轉換爲順序操作。

您需要確保在循環中發生的任何事情都是安全的。

微軟的模式和實踐做了a book,解釋了所有這些和更多。在更改代碼以使用並行循環之前,應該先檢查一下。

2

肯定地說 - 張貼您的迭代/循環代碼。

但總體而言,您的迭代應該彼此獨立並儘量避免共享狀態。並行迭代資源中的任何共享資源都可能引入錯誤。

另外,當您的計算依賴於某些其他計算或並行操作或循環更好地使用TPL任務鏈時,它也有助於避免共享跨線程資源。

更多infromation和樣品和模式/反模式是很好的免費的Microsoft書中描述:瞭解和應用並行模式與.NET Framework 4

在這裏下載

http://www.microsoft.com/en-us/download/details.aspx?id=19222:並行編程模式