2017-04-15 107 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中推荐? –