2017-04-15 153 views
2

據:http://www.cplusplus.com/reference/cstdlib/rand/替代rand()以避免競爭條件?

在C中,通過使用蘭特的生成算法是保證只有 通過調用該函數前進。在C++中,這個限制是寬鬆的,並且允許庫實現在其他情況下(例如調用元素 )前進 生成器。

但隨後在這裏,它說:

功能訪問和修改內部狀態的對象,這可能與併發調用蘭特或函數srand 導致數據爭。

某些庫提供了一種替代功能,明確避免了這種數據競爭:rand_r(不可移植)。

允許C++庫實現保證調用此函數的 沒有數據競爭。

理想我想有某種蘭特的「實例」,從而使該實例,和給定的種子,我總是生成的數字呼叫同一序列該實例。在當前版本中,似乎在某些平臺上,其他函數調用rand()(甚至可能在不同的線程上)可能會影響我的代碼在我的線程中生成的數字序列。

是否有替代方案,在那裏我可以抓住某種「實例」,在這裏我保證生成特定序列,給予種子,並在其他調用不同的「實例」不影響它?編輯:爲了清晰起見 - 我的代碼將運行在多個不同的平臺上(iOS,Android,Windows 8.1,Windows 10,Linux等),並且我目前無法測試每個實現。我只想根據標準保證的東西來實現...

+2

查看C++ 11的隨機數特性:http://en.cppreference.com/w/cpp/numeric/random – aschepler

+0

@aschepler我不太在意數字是如何「隨機」的。有很多不同的引擎,要花很長時間才能找出哪一個在問什麼問題。 –

+1

好的,但新的方法可以讓你存儲所有的狀態,但是你想要的,而不是依靠一些全球性國家。 – aschepler

回答

5

您可以使用std::uniform_int_distributionstd::mt19937保持發電機與您共同種子(均來自<random>庫)。

std::mt19937 gen(SEED); 
std::uniform_int_distribution<> dis(MIN, MAX); 
auto random_number = dis(gen); 

這裏,SEED是要指定的種子編號。

std::mt19937 gen{}; 
gen.seed(SEED); 

如果你需要生成一個,你可以使用std::random_device爲:

std::random_device rd{}; 
std::mt19937 gen(rd()); 

dis(MIN, MAX)部分設置範圍最小和最大的您可以與.seed方法太稍後設置另一個種子這個分佈的值可能會出現,這意味着它永遠不會產生大於MAX或小於MIN的值。

最後,你可以使用你的發電機與這個分佈產生你想要的隨機值,如下所示:dis(gen)。分佈可以採用任何生成器,所以如果你想要其他分佈具有相同的隨機數序列,你可以複製gen,或者使用相同的種子並構建兩個或更多的生成器。

+0

這是STL的一部分嗎? –

+0

@KaizerSozay,是的,它來自標準的C++庫。 –

+0

Dis和gen完全獨立於std :: mt19937和std :: uniform_int_distribution的其他實例嗎?我無法在鏈接到的文檔中找到它... –

1
+0

安全對我的目的並不重要。你能解釋爲什麼隨機更好嗎?我可以播種它,並獲得相同的序列? –

+0

random()不是STL的一部分..是否有任何東西在STL中推薦? –