替代rand()以避免竞争条件?

时间:2017-04-15 01:26:26

标签: c++ c++11

根据:http://www.cplusplus.com/reference/cstdlib/rand/

  

在C中,rand使用的生成算法仅保证   通过调用此函数进行调整。在C ++中,这个约束是   放松,并允许图书馆实施推进   生成器在其他情况下(例如对元素的调用)   )。

然后在这里它说:

  

该函数可以访问和修改内部状态对象   导致与rand或srand的并发调用的数据争用。

     

某些库提供了明确避免的替代功能   这种数据竞争:rand_r(非便携式)。

     

允许C ++库实现保证没有数据争用   调用这个函数。

理想情况下,我想拥有rand的某种“实例”,因此对于该实例和给定的种子,我总是为调用 THAT实例生成相同的数字序列。对于当前版本,似乎在某些平台上,其他函数调用rand()(甚至可能在不同的线程上),可能会影响我的代码在我的线程中生成的数字序列。

是否存在替代方案,我可以保留某种“实例”,我保证在给定种子的情况下生成特定序列,以及对不同“实例”的其他调用不会影响它? / p> 编辑:为了清楚起见 - 我的代码将在多个不同的平台(iOS,Android,Windows 8.1,Windows 10,Linux等)上运行,我目前无法测试每个实现。我只想根据标准保证的内容来实现......

2 个答案:

答案 0 :(得分:5)

您可以使用std::uniform_int_distributionstd::mt19937来保护生成器与您的公共种子(所有来自<random>库)。

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

此处,SEED是您要指定的种子编号。您也可以稍后使用.seed方法设置另一个种子:

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

如果您需要生成一个,可以使用std::random_device

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

dis(MIN, MAX)部分设置此分布可以出现的最小值和最大值范围,这意味着它永远不会生成大于MAX或小于MIN的值。

最后,您可以使用此分布生成器生成所需的随机值,如下所示:dis(gen)。分布可以使用任何生成器,因此如果您希望其他分布具有相同的随机数序列,您可以复制gen,或使用相同的种子并构建两个或更多生成器。

答案 1 :(得分:1)