【问题标题】:Perl File::Temp, file name not randomPerl File::Temp,文件名不是随机的
【发布时间】:2013-07-10 21:02:47
【问题描述】:

我在使用File::Temp时遇到了一个奇怪的问题:

我在 Linux 上的 Apache 中的 mod_perl 下运行我的 perl 脚本,Apache 使用 worker mpm 运行。

my ($fh_error, $error)
    = tempfile("error_XXXXXXXXXXXXXXXX",DIR => "/home/tmp", UNLINK => 1);
my ($fh_src, $src) 
    = tempfile("src_XXXXXXXXXXXXXXXX",DIR => "/home/tmp", UNLINK => 1, SUFFIX => ".html");          
my ($fh_dst, $dst) 
    = tempfile("dst_XXXXXXXXXXXXXXXX",DIR => "/home/tmp", UNLINK => 1, SUFFIX => ".html");

大多数时候,一切似乎都很好,但时不时我会得到一些错误的文件名。 我没有得到真正的随机文件名,而是得到所有模板长度的相同字母。

例如

error_AAAAAAAAAAAAAAAA
src_AAAAAAAAAAAAAAAA
dst_AAAAAAAAAAAAAAAA

所有 3 个文件的名称相同。 除了这很奇怪(而且你永远不希望你的代码很奇怪)之外,我担心这可能会导致读取/写入同一个文件以针对不同的请求。

【问题讨论】:

  • 猜测:也许你的熵用完了?您是否在系统上运行了 munin(或类似的东西),您是否在“可用熵”图中看到了可疑的东西?
  • 他妈的还没想到,现在100-200有点低
  • 是的,但即使熵为零,/dev/urandom 仍应继续提供良好的伪随机数。它们只是在密码学上不强(即,对于足够大的 N,使用 N 个连续的随机数,理论上您可以计算出 N+1 的更好几率)。

标签: perl mod-perl temporary-files


【解决方案1】:

我查看了File::Temp 的来源。它用这个简洁的 perl 替换模板中的 X:

    $path =~ s/X(?=X*$end)/$CHARS[ int( rand( @CHARS ) ) ]/ge;

它使用 perl 的内置 rand,它只是一个传统的基于种子的随机数生成器。 rand 函数在密码学上不是安全的。它的种子也是“全局状态”,在分叉时可能会导致问题,如下所述:

http://blogs.perl.org/users/brian_phillips/2010/06/when-rand-isnt-random.html

它的要点是:如果你 fork 两个 perl 解释器,并且原始解释器已经通过对 rand 的一次调用作为种子,两者都在 fork 之后继承相同的种子,所以两者都会生成相同的随机数从那一点开始的数字序列。哎呀。因此,您可能希望在调用tempfile 或其他任何调用rand 之前在您的模块中调用srand

也就是说,File::Temp 似乎非常努力地检测和避免碰撞,但它会在某个时候放弃。以下警告隐藏在 File::Temp 文档中:

    If you are forking many processes in parallel that are all creating 
    temporary files, you may need to reset the random number seed using 
    srand(EXPR) in each child else all the children will attempt to walk 
    through the same set of random file names and may well cause themselves 
    to give up if they exceed the number of retry attempts.

【讨论】:

  • 我自己做了一些挖掘,也发现了这个问题,我还发现了一个建议将PerlChildInitHandler sub { srand }添加到apache conf,但它似乎没有用
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-11-29
  • 2012-03-29
  • 2023-03-28
  • 2017-02-23
  • 1970-01-01
相关资源
最近更新 更多