线程安全使用<random>

Thread-safe using of <random>

本文关键字:random gt 安全 lt 线程      更新时间:2023-10-16

stl在他对本地的演讲中说

多个线程不能同时调用一个对象。

(在线pptx文件上的最后一个幻灯片。)

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

只需创建多个副本即可。分发是一个轻巧的物体,比保护它需要的静音要便宜。

您永远不会使用PRNG足够长的时间,以便从中看到完全均匀的分布。您应该只看到均匀分布的随机近似。给出每个线程自己的prng的事实意味着每个线程都需要更长的 numThreads倍才能看到完美的分布无关紧要。

prng经过数学分析,以确认它们会产生每个可能的输出次数,但这并不反映它们的意思。

如果使用这种方式,则代表A 弱点。如果您观看足够长的时间,您会知道已经看到输出x n次,并且所有其他输出n+1次,下一个输出必须为x。这是统一的,但显然不是随机的。

真正的RNG永远不会产生完全均匀的输出,但它也不应两次表现出相同的偏见。每次使用时,已知具有不均匀输出的PRNG将具有相同的不均匀输出。这意味着,如果您进行更长的模拟以平均消除噪声,那么PRNG自己的偏见最终将成为最重要的因素。因此,理想的prng最终应该在足够长的时间内发出完美统一的分布(实际上通常不是完美,但在已知的,非常小的边距内)。。

您的随机种子会在该顺序中选择一个随机点,并且您的随机数请求将按照该顺序进行某种方式,但是如果您发现自己一路走动并回到您自己的起点(甚至什至在1/10之内),然后您需要获得更大的prng。

也就是说,还有另一个考虑因素。通常使用PRNG,以便可以预测其结果。

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

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

定义随机生成器引擎时也可以使用thread_local存储(假设您只想在程序中声明一个)。这样,每个线程将可以访问其"本地"副本,因此您将无法进行任何数据竞赛。您不能仅在所有线程中使用单个引擎,因为在生成序列中更改状态时可能会有数据竞赛条件。