什么可能导致gunzip / gzip挂起Perl线程?

时间:2014-05-28 14:19:10

标签: multithreading perl gzip pipe zombie-process

我写的脚本有多个线程。这些线程中的每一个都负责相当数量的IO。我使用的是Perl 5.8.3。

需要进行以下文件处理:
1)打开一个gzip压缩文件,将内容读入一些变量 2)关闭来自gzip / gunzip的输入流 3)根据变量中的数据执行任意计算。

我尝试了几种不同的方法来解压缩文件以获取文件内容:

$someVariable = `gunzip -c /path/to/file.gz`;

$someVariable = "";
open(my $INPUT,'gunzip -c /path/to/file.gz|');

while(my $line = <$INPUT>){
    $someVariable .= $line;
}
close($INPUT);

这个过程通常预计需要花费数小时,但是gunzip似乎卡在随机文件上。读取的文件没有什么特别之处。卡住的每次都是不同的,有些时候根本没有文件被卡住(处理相同的批次)。这是过程信息的样子(使用ps aux | grep gunzip):

username 12345  0.0  0.0   1752   400 pts/3    S    May27   0:00 gunzip -c /path/to/file.gz

我愿意接受有关该计划的建议和问题。我只能发布代码的通用部分。另外,我已经阅读了这篇文章(How to deal with multiple threads in perl which turn into zombie)。我似乎遇到了类似'Gahoo'的问题,但是没有发布解决方案(他的最终评论表明与我所遇到的问题有关)。

谢谢!
保罗

3 个答案:

答案 0 :(得分:1)

假设您已经纠正了它的反引号或open -|,那么它是Perl中的一个错误,它可能是众多线程错误中的一个。自从已有五十年历史的5.8.3。

答案 1 :(得分:0)

我在使用Cygwin在Windows中调度的Perl线程中进行gzipping时遇到过这个问题。但是,在使用Linux调度的Perl线程中进行gzipping时,不会出现此问题。这让我相信这是一个 Cygwin 错误。您有两种方法可以解决此问题:

  1. 在Linux中运行脚本。
  2. 使用IO :: Uncompress :: Gunzip(http://perldoc.perl.org/IO/Uncompress/Gunzip.html)代替gzip / gunzip。这个实现不会挂起,但它会慢得多。

答案 2 :(得分:0)

我遇到了在Linux上运行更晚版本(5.20.1)的同样问题。虽然我没有找到明确的解决方案,但我确实提出了一种解决方法,即使用system()调用gunzip并将输出重定向到临时文件(我用线程#附加临时文件),然后读取在该临时文件中使用标准的open()调用。基于此,似乎问题在于使用上面的gzip方法时使用stdout。这种解决方法远非理想,可能会更加强大,但在某些情况下是可以接受的。 例如:

system("gunzip -c $filename > tmp_file".threads->tid());
open FOO, "<", "tmp_file".threads->tid() or die $!;
$output = <FOO>;
close FOO;