线程安全使用<random>

时间:2015-05-07 15:04:14

标签: c++ multithreading c++11 random thread-safety

STL在his lecture on Going Native上说,

  

多个线程无法同时调用单个对象。

pptx file online上的最后一张幻灯片。)

如果我需要跨多个线程(不是线程的独立随机生成器)均匀分布随机数,如何从多个线程正确使用相同的uniform_int_distribution?或者根本不可能?

3 个答案:

答案 0 :(得分:3)

只需创建多个副本。分发是一个轻量级对象,比你需要保护它的互斥锁便宜。

答案 1 :(得分:1)

你永远不会想要使用PRNG足够长的时间,你可以从中看到完全均匀的分布。您应该只看到均匀分布的随机近似。为每个线程提供自己的PRNG这一事实意味着每个线程需要numThreads倍的时间才能看到完美的分布并不重要。

PRNG需要进行数学分析,以确认它们产生的每个可能的输出次数相同,但这并不能反映出它们的使用方式。

如果以这种方式使用它,则表示弱点。如果你观看的时间足够长,你知道看到输出x n次,而其他输出n+1次,则下一个输出必须是x。这是统一的,但显然不是随机的。

真正的RNG永远不会产生完美均匀的输出,但它也不应该两次显示相同的偏差。已知具有非均匀输出的PRNG在每次使用时将具有相同的非均匀输出。这意味着,如果您运行模拟更长时间来平均噪声,PRNG自身的偏差最终将成为最具统计意义的因素。因此理想的PRNG最终应该在足够长的时间内发出完全均匀的分布(实际上通常并不完美,但在已知的非常小的范围内)

你的随机种子将在该序列的某个地方选择一个随机点,你的随机数请求将按照该序列的某种方式进行,但是如果你发现自己一路走来并回到自己的起点(甚至在距离的1/10之内)那么你需要获得更大的PRNG。

那就是说,还有另一个考虑因素。 PRNG经常被专门使用,以便他们的结果可以预测。

如果您需要互斥锁来安全访问单个PRNG,那么您可能已经失去了可预测的行为,因为您无法告诉哪个线程获得了下一个[可预测的]随机数。每个线程仍然会看到一个不可预测的序列,因为您无法确定它获得的PRNG结果的子集。

如果每个线程都有自己的PRNG,那么(只要必要时满足其他排序约束),您仍然可以获得可预测的结果。

答案 2 :(得分:0)

您还可以在定义随机生成器引擎时使用thread_local存储(假设您只想在程序中声明一个)。通过这种方式,每个线程都可以访问&#34; local&#34;它的副本,所以你没有任何数据竞赛。您不能只在所有线程中使用单个引擎,因为在生成序列期间更改其状态时可能会有数据争用条件。

相关问题