【问题标题】:How to generate a good random seed to pass to srand()?如何生成一个好的随机种子传递给 srand()?
【发布时间】:2010-02-02 14:26:57
【问题描述】:

我正在编写一个 C++ 程序,它需要为其内部使用创建一个临时文件。我想通过运行多个进程来允许程序的并发执行,所以临时文件名需要随机化,这样每个生成的进程都会生成一个唯一的临时文件名供自己使用。

我正在使用 rand() 为部分文件名生成随机字符,因此我需要使用 srand() 初始化随机数生成器的种子。

有哪些选项可以将一个好的参数传递给 srand(),这样两个进程就不会使用相同的种子值进行初始化? 我的代码需要同时在 Windows 和 Linux 上运行。

【问题讨论】:

    标签: c++ c random


    【解决方案1】:

    问题是实际上询问如何创建一个唯一命名的临时文件。

    操作系统可能为此提供了一个 API,这意味着您不必生成自己的名称。

    在 Windows 上,它称为GetTempFileName() and GetTempPath()

    在 Unix 上,使用 tmpfile()

    (Windows 也支持tmpfile();但是,我听到其他人的报告说,虽然它在 XP 上运行良好,但如果你在 C: 驱动器上并且你不是管理员,它在 Vista 上就会失败;最好使用带有自定义安全路径的GetTempFileName() 方法)

    【讨论】:

    【解决方案2】:

    如果你真的只需要一个临时文件,你可以使用:

    FILE* tmpfile();        // Generate an unnamed temporary file.
    char* tmpnam(char* s);  // Generate a file name in the director specified by TMPDIR
    

    使用时间:

    srand(time(NULL));
    

    还要注意 rand() 可能不是线程安全的。
    所以要小心你如何使用它。两个线程同时进入rand会出问题。

    【讨论】:

    • @Martin York:如果我在同一秒内产生两个进程,它们都将以相同的种子启动。事实上,即使是毫秒级的分辨率也可能足够好。不过,不错的尝试。
    • 这不正是您想要的吗?该问题明确指出您需要两个并发进程,这意味着两个线程。
    • @zr:如果您是手动启动,这不太可能。如果它们是由脚本启动的,则在两个进程的启动之间休眠。或者在一个应用程序中使用 rand(time(NULL)+10000)。
    • 如果它们是两个进程,那么您不必担心 rand() 的并发性,因为每个进程都有自己的 rand() 副本。如果它们是两个线程,那么您就遇到了您正在谈论的问题。
    • @rmeador:还有另一个“Captain Obvious”奖。我认为应该有一个名为“Captain Obvious”的新徽章,我们可以将其奖励给指出正确但即使是最新的菜鸟也很明显的人,建议。
    【解决方案3】:

    我自己从未使用过它,但您也许可以使用tmpnam() 来生成您的临时文件名。快速搜索表明支持WindowsLinux

    【讨论】:

      【解决方案4】:

      你可以得到以微秒为单位的时间,然后将它乘以一个大数来得到一个种子。但是,无论种子是什么,冲突总是会发生。

      【讨论】:

        【解决方案5】:

        在 unix 系统上,从 /dev/random 中读取一个值

        【讨论】:

          【解决方案6】:

          不同的进程会有不同的进程ID。但是,将其直接添加到时间会有点粗心,因为它通常是一个很小的数字。不过这不是一个大问题:根本问题是时间和进程 ID 的熵都集中在最低位。通过简单地对其中一个进行位反转并对结果进行异或运算,您可以获得所有位的良好熵。

          【讨论】:

            【解决方案7】:

            我建议您不要使用随机文件名,而是根据进程 id 和当前时间创建一个唯一的文件名(如果您可以读取的时间分辨率对您来说足够,那么应该是)。我对您的问题知之甚少,但我怀疑使用随机名称没有任何好处,而且发生冲突的风险可能非常真实。即使您使用操作系统为您创建另一个答案中建议的文件也是如此。

            【讨论】:

              猜你喜欢
              • 2016-07-13
              • 1970-01-01
              • 2011-02-08
              • 2011-08-25
              • 1970-01-01
              • 2021-05-15
              • 1970-01-01
              • 1970-01-01
              • 2011-06-11
              相关资源
              最近更新 更多