Perl的rand()函数以localtime作为种子

Cur*_*Sid 0 random perl random-seed

请看下面的代码:

srand(localtime);

for (my $ik = 0; $ik < 3; $ik += 1)
{
    print int(rand(10)),"\n";
    sleep(1);
}
Run Code Online (Sandbox Code Playgroud)

我在中间有足够的时间(5-10秒)多次调用上面的代码,但输出顺序仍然相同.

因为我已经将种子设置为localtime每个调用必须使用不同的种子,并且可能由于时间间隔而生成不同的三个数字序列.为什么我一次又一次地得到相同的序列.

注意:代码不在循环中,它位于多次执行的Perl文件中.

文档说如果多个实例在导致相同种子的相同"秒"中运行,则此种子会失败 - 在这种情况下并非如此.

编辑:: @simbabque的解决方案确实有所帮助,但未获得预期的随机性.请看下面对上述解决方案的评论.

sim*_*que 7

尝试用use strict和运行它use warnings.它会给你:

Argument "Thu Jun 21 13:04:41 2012" isn't numeric in srand at ...

就是你的问题.localtime在标量上下文中返回一个字符串.尝试使用time,它将unix时间戳作为整数返回.srand需要一个数值来工作.

如果你向它添加一个Data :: Dumper,你会看到代码的种子总是如此1.

no strict; no warnings;
use Data::Dumper;
print Dumper srand(localtime);

for (my $ik = 0; $ik < 3; $ik += 1)
{
    print int(rand(10)),"\n";
    sleep(1);
}
Run Code Online (Sandbox Code Playgroud)

说:

$VAR1 = 1;
0
2
6
Run Code Online (Sandbox Code Playgroud)

你需要的是:

use strict; use warnings;
srand(time);
for (my $ik = 0; $ik < 3; $ik += 1)
{
    print int(rand(10)),"\n";
    sleep(1);
}
Run Code Online (Sandbox Code Playgroud)

编辑:

如果你想要良好的随机性,这仍然不是一个好主意.医生说:

在5.004之前的Perl版本中,默认种子只是当前时间.这不是一个特别好的种子,所以许多旧程序提供他们自己的种子价值(经常time ^ $$time ^ ($$ + ($$ << 15))),但这不再是必要的.

srand除非你真的想要可重复的结果(即用于测试),否则我建议你完全忽略调用.