【问题标题】:Does one need to call srand() C function per thread or per process to seed the randomizer?是否需要为每个线程或每个进程调用 srand() C 函数来为随机发生器播种?
【发布时间】:2012-04-15 05:12:20
【问题描述】:

标题几乎说明了这一点。

PS。这是针对 C++ Windows 程序的。

【问题讨论】:

  • 请出示您的代码...

标签: c++ windows random random-seed


【解决方案1】:

根据the MSDN documentation on srand()(假设您使用的是Microsoft 的C 运行时库),种子是线程本地的,因此您需要为每个使用rand() 的线程调用srand()。请注意,在其他实现中可能并非如此。

引用自 MSDN:

srand 函数设置在当前线程中生成一系列伪随机整数的起点。

【讨论】:

  • 我认为这是不标准的。
  • @Nawaz:它是非标准的,POSIX 不需要 srand()rand() 是线程安全的。
  • 谢谢。我错过了。所以,是的,似乎每个线程都需要先播种……真是麻烦。
  • rand()的重点是它从一个种子开始生成一个固定的序列。当来自其他线程的调用可以修改调用线程获取的序列时,很难看出这有什么用。 (当然,这是一个公平的论点,即使这是一个修复,它也是一个地雷,因为该函数具有相同的名称但不同的语义。)
【解决方案2】:

即使答案不是特定于平台的,我也建议您避免使用srand() 并改用<random>。 C++11 <random> 库不仅在多线程程序中提供了清晰的语义,而且还为随机数生成提供了更好的工具。它提供了几种不同的随机数生成器来满足不同的质量、速度和大小要求,以及许多标准分布,因此您不会犯人们在使用rand 时经常犯的错误。

【讨论】:

  • 我可以在使用MFC编写的MS VS 2008 C++程序中使用它吗?
  • 我认为是在VS2010中添加的,但是和MFC没有冲突@ahmd0
【解决方案3】:

不,根据标准,因为一旦您调用 srand(),它会影响来自所有线程的 rand() 调用。

C 库函数srand() 与所有其他函数一样是单线程的,这意味着如果您从一个线程调用srand(),它也会影响其他线程中从rand() 生成的数字序列。

但微软提供了非标准的srand()确实要求你从所有线程中调用它。

【讨论】:

  • 好吧,从技术上讲,这也是正确的答案,尽管您应该在开场白中说“是”——意思是,是的,每个线程都调用它,对 ))跨度>
  • @ahmd0:按照标准,它应该是No
  • 微软违反的唯一标准是 POSIX 线程标准和 C++11 标准,微软声称不符合这两个标准。微软的功能不是非标准的,它符合 Windows 线程标准,这在很多方面与 POSIX 标准不同。这只是其中之一。 (微软做对了,POSIX/ISO 做错了。见我上面的评论。)
  • @DavidSchwartz Microsoft 声称支持 c++11。特别是我听说 Herb Sutter 说他们已经完全支持 C++11 标准库。 (当然我知道一些在其他领域不正确的方法,因为缺乏语言特性)
  • @bames53 我的消息来源只说他们正在添加许多 C++11 功能并努力实现 C++11 合规性。就在两个月前,他们向开发人员发送了一份调查问卷,要求他们优先考虑 C++11 功能,以帮助他们决定要添加什么。我想知道声称符合 C++11 的版本是否会有“固定”srand。 (我不能 100% 确定符合 C++11 的要求,但我相信确实如此。)
【解决方案4】:

请注意,状态是光纤本地的(比线程本地更细粒度)。因此,必须为每根光纤调用 srand。 (当然,当你不使用 Fiber 时,它相当于 thread-local。)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-01-05
    • 1970-01-01
    • 1970-01-01
    • 2014-05-29
    • 2014-06-02
    • 1970-01-01
    相关资源
    最近更新 更多