2012-08-23 94 views
2

我在閱讀this section,最後一段指出示例代碼不是線程安全的。我的問題是:這不會有助於增加它的隨機性(即如果多個線程同時執行這些線)?非線程安全性是否會增加具有隨機僞隨機數生成器的隨機性?

+0

你有沒有聽說過競賽條件這個詞? –

+0

是的,我有;但這就是要點。不是種族條件可能是隨機活動的來源?難道這不會爲代碼添加另一層隨機性嗎? – Adib

+0

PNRG可能被設計爲具有很好的輸出屬性。這並不一定意味着它的中間計算狀態是隨機的,如果你有競爭條件,這就是你閱讀的內容。 – TJD

回答

7

PRNG經過精心設計(當然也可能不是RANDU)以產生可預測且足夠隨機分佈的結果。他們不必是真正的隨機,他們只需要滿足統計質量測試,產生一個足夠長的時間,並用同一顆種子確定。

如果您碰巧從多個線程同時使用發生器,那麼所有這些保證都會消失。最重要的是,你不能有一個可重複的結果(這在模擬中是非常重要的)。然後,狀態可能會改變,或者你可能在不同的線程中兩次獲得相同的數字,這些事情。

你絕對不想去那裏。每個線程創建一個PRNG(最好使用線性獨立的種子)。

+0

所以如果我做一個非線程安全的PRNG(並且它不會像Sean提到的那樣破壞內部狀態),我能獲得一個'幾乎'的RNG嗎? – Adib

+0

沒有理由甚至嘗試這樣做。首先,線程不安全是非常不可預測的,所以你沒有任何依賴於可能發生的事情。其次,PRNGs通常具有非常特定的用途,並且這些用途需要保證他們對序列做出的保證。 – Joey

+3

@someDude比賽條件不是比特加擾器。最可能的結果是一些中間值將繼續被重用。它發生的模式將是不可預測的,所以這裏有一個隨機元素。但那個舊的「九九九」[Dilbert卡通](http://search.dilbert.com/comic/Random%20Nine)仍然浮現在腦海。 –

4

非線程安全隨機數生成器的一個可能的副作用是您可以以某種方式破壞內部狀態。例如,如果您從兩個不同的線程訪問.NET的Random的相同實例,則可以將其置於一直處於不斷返回0的狀態。

在你連接的RNG中,它看起來並不是特定的問題可能發生,但它可能會有一些退化的併發訪問模式將m_zm_w設置爲0,根據註釋也可能不好。

+1

正如一邊,有[簡單的方法](http://stackoverflow.com/a/11109361/238419)使用.Net的「隨機」類建立一個線程安全版本。 –

0

你絕對可以從線程定時生成中獲得熵,但將熵收集和僞隨機數生成混合成前者可能干擾後者的其他方式可證明的屬性的方式是非常糟糕的主意 - 很像喬伊說。我添加新答案的原因是,您可能會考慮將真實熵與您的PRNG混合(不管是種子還是定期引入更多),並從不同線索收集實時定時信息是熵的一個可能來源。然而,它應該嚴格地進行(通過適當的鎖定或無鎖的原子操作來存儲結果),而不是通過調用未定義的行爲並希望得到熵。

0

代碼是非線程安全的有很多方法。

一種方法是線程無法看到寫入其他線程所做的內存。

我們可能會發現隨機數生成產生全零,因爲它從不「看到」其他線程完成的工作。