2012-08-23 100 views
2

我在阅读this section,最后一段指出示例代码不是线程安全的。我的问题是:这不会有助于增加它的随机性(即如果多个线程同时执行这些线)?非线程安全性是否会增加具有随机伪随机数生成器的随机性?

+0

你有没有听说过竞赛条件这个词? –

+0

是的,我有;但这就是要点。不是种族条件可能是随机活动的来源?难道这不会为代码添加另一层随机性吗? – Adib

+0

PNRG可能被设计为具有很好的输出属性。这并不一定意味着它的中间计算状态是随机的,如果你有竞争条件,这就是你阅读的内容。 – TJD

回答

7

PRNG经过精心设计(当然也可能不是RANDU)以产生可预测且足够随机分布的结果。他们不必是真正的随机,他们只需要满足统计质量测试,产生一个足够长的时间,并用同一颗种子确定。

如果您碰巧从多个线程同时使用发生器,那么所有这些保证都会消失。最重要的是,你不能有一个可重复的结果(这在模拟中是非常重要的)。然后,状态可能会改变,或者你可能在不同的线程中两次获得相同的数字,这些事情。

你绝对不想去那里。每个线程创建一个PRNG(最好使用线性独立的种子)。

+0

所以如果我做一个非线程安全的PRNG(并且它不会像Sean提到的那样破坏内部状态),我能获得一个'几乎'的RNG吗? – Adib

+0

没有理由甚至尝试这样做。首先,线程不安全是非常不可预测的,所以你没有任何依赖于可能发生的事情。其次,PRNGs通常具有非常特定的用途,并且这些用途需要保证他们对序列做出的保证。 – Joey

+3

@someDude比赛条件不是比特加扰器。最可能的结果是一些中间值将继续被重用。它发生的模式将是不可预测的,所以这里有一个随机元素。但那个旧的“九九九”[Dilbert卡通](http://search.dilbert.com/comic/Random%20Nine)仍然浮现在脑海。 –

4

非线程安全随机数生成器的一个可能的副作用是您可以以某种方式破坏内部状态。例如,如果您从两个不同的线程访问.NET的Random的相同实例,则可以将其置于一直处于不断返回0的状态。

在你连接的RNG中,它看起来并不是特定的问题可能发生,但它可能会有一些退化的并发访问模式将m_zm_w设置为0,根据注释也可能不好。

+1

正如一边,有[简单的方法](http://stackoverflow.com/a/11109361/238419)使用.Net的“随机”类建立一个线程安全版本。 –

0

你绝对可以从线程定时生成中获得熵,但将熵收集和伪随机数生成混合成前者可能干扰后者的其他方式可证明的属性的方式是非常糟糕的主意 - 很像乔伊说。我添加新答案的原因是,您可能会考虑将真实熵与您的PRNG混合(不管是种子还是定期引入更多),并从不同线索收集实时定时信息是熵的一个可能来源。然而,它应该严格地进行(通过适当的锁定或无锁的原子操作来存储结果),而不是通过调用未定义的行为并希望得到熵。

0

代码是非线程安全的有很多方法。

一种方法是线程无法看到写入其他线程所做的内存。

我们可能会发现随机数生成产生全零,因为它从不“看到”其他线程完成的工作。