为什么这个 Perl 脚本 运行 内存逐渐不足
Why this Perl script run out of memory gradually
我在 运行 多线程 Perl 脚本中遇到问题。它继续消耗内存,最后系统 运行 内存不足并将其杀死。似乎子线程被分离了,但是当它们完成时系统资源没有被释放。我是 Perl 的新手,找不到哪个部分出了问题。这是可能导致此问题的脚本的一部分。谁能帮我解决这个问题?
use strict;
use warnings;
print "different number:\t";
my $num1=<>;
chomp $num1;
if($num1!~/[1 2 3 4 5]/)
{
print "invalid input number\n";
END;
}
my $i=0;
my $no;
my @spacer1;
my $nn;
my @spacer2;
open IN,"file1.txt"or die"$!";
while(<IN>)
{
chomp;
if($_=~ /^>((\d)+)\|((\d)+)/)
{
$no=;
$spacer1[$no][0]=;
}
else
{
$spacer1[$no][1]=$_;
}
}
close IN;
open IN, "file2.txt" or die "$!";
while(<IN>)
{
chomp;
if($_=~ /^>((\d)+)\|((\d)+)/)
{
$nn=;
$spacer2[$nn][0]=;
}
else
{
$spacer2[$nn][1]=$_;
}
}
close IN;
#-----------------------------------------------------------------#create threads
use subs qw(sg_ana);
use threads;
use Thread::Semaphore;
my $cycl=(int($no/10000))+1;
my $c;
my @thd;
my $thread_limit= Thread::Semaphore -> new (3);
foreach $c(1..$cycl)
{
$thread_limit->down();
$thd[$c]=threads->create("sg_ana",$c-1,$c,$num1);
$thd[$c]->detach();
}
&waitquit;
#-------------------------------------------------------------#limite threads num
sub waitquit
{
print "waiting\n";
my $num=0;
while($num<3)
{
$thread_limit->down();
$num++;
}
}
#---------------------------------------------------------------#alignment
my $n;
my $n1;
my $j;
my $k;
my $l;
my $m;
my $num;#number of match
my $num2=0;;#arrange num
sub sg_ana
{
my $c1=shift;
my $c2=shift;
$num1=shift;
open OUT,">$num1.$c2.txt" or die "$!";
if($num1==1)
{
foreach $n($c1*10000..$c2*10000-1)
{
if($spacer2[$n][1])
{
my $presult1;
my $presult2;
$num2=-1;
foreach $i(0..19)
{
$num=0;
$num2++;
my $tmp1=(substr $spacer2[$n][1],0,$i)."\"."w".(substr $spacer2[$n][1],$i+1,19-$i);
foreach $n1(0..@spacer1-1)
{
if($spacer1[$n1][1])
{
my $tmp2=substr $spacer1[$n1][1],0,20;
if($tmp2=~/$tmp1/)
{
$num++;
$presult1.=$n1.",";
}
}
}
$presult2=$i+1;
if($num>=4)
{
print OUT "\n";
}
}
}
}
}
close OUT;
$thread_limit->up();
}
- 调试 perl 的规则一是启用
use strict;
和 use
warnings;
,然后整理错误。其实你应该
可能首先要这样做,甚至在您开始编写代码之前。
- 您正在通过信号量创建和限制线程 - 但实际上
这真的很低效,因为
perl
如何处理线程 - 它们
不是轻量级的,所以产生负载是个坏主意。更好的方法是通过 Thread::Queue
a bit like this.
- 请使用 3 个 arg 打开和词法文件句柄。例如
open ( my
$out, '>', "$num.$c2.txt" ) or die $!;
。你可能会得到
在这里去掉它,但是你有 OUT
作为全局命名空间
变量被多个线程使用。那边有龙。
不要使用单字母变量。考虑到你如何使用 $c
那么你会 远 更好:
foreach my $value ( 1..$cycl ) {
## do stuff
}
所有 other 单字母变量也是如此 - 它们没有意义。
你在初始化之前传递 $num
,所以它总是
在你的子中 undef
。所以你的实际子程序只是:
sub sg_ana
{
my $c1=shift;
my $c2=shift;
$num1=shift;
open OUT,">$num1.$c2.txt" or die "$!";
close OUT;
$semaphore->up();
}
看看它 - 我认为您 可能 正在尝试使用那里的共享变量做一些事情,但您实际上并没有共享它。我无法解码你程序的逻辑(由于很可能有大量的单字母变量)所以我不能肯定地说。
- 您正在调用子程序
&waitquit;
。那不是好风格-
以&符号为前缀并且不提供任何参数
与仅调用 sub 'normally' 略有不同 - 所以
你应该避免它。
不要像这样实例化你的信号量:
my $semaphore=new Thread::Semaphore(3);
这是一个间接过程调用,风格很差。最好写成:
my $thread_limit = Thread::Semaphore -> new ( 3 );
我建议不要像那样使用信号量,你最好不要 detatch
使用你的线程,只使用join
。您也不需要线程数组 - threads -> list
会为您完成。
我无法重现你的问题,因为你的潜艇没有做
任何事物。您是否有机会修改它以供发布?但是线程化时 perl 内存耗尽的一个典型原因是因为每个线程都克隆父进程 - 因此 100 个线程是内存的 100 倍。
我在 运行 多线程 Perl 脚本中遇到问题。它继续消耗内存,最后系统 运行 内存不足并将其杀死。似乎子线程被分离了,但是当它们完成时系统资源没有被释放。我是 Perl 的新手,找不到哪个部分出了问题。这是可能导致此问题的脚本的一部分。谁能帮我解决这个问题?
use strict;
use warnings;
print "different number:\t";
my $num1=<>;
chomp $num1;
if($num1!~/[1 2 3 4 5]/)
{
print "invalid input number\n";
END;
}
my $i=0;
my $no;
my @spacer1;
my $nn;
my @spacer2;
open IN,"file1.txt"or die"$!";
while(<IN>)
{
chomp;
if($_=~ /^>((\d)+)\|((\d)+)/)
{
$no=;
$spacer1[$no][0]=;
}
else
{
$spacer1[$no][1]=$_;
}
}
close IN;
open IN, "file2.txt" or die "$!";
while(<IN>)
{
chomp;
if($_=~ /^>((\d)+)\|((\d)+)/)
{
$nn=;
$spacer2[$nn][0]=;
}
else
{
$spacer2[$nn][1]=$_;
}
}
close IN;
#-----------------------------------------------------------------#create threads
use subs qw(sg_ana);
use threads;
use Thread::Semaphore;
my $cycl=(int($no/10000))+1;
my $c;
my @thd;
my $thread_limit= Thread::Semaphore -> new (3);
foreach $c(1..$cycl)
{
$thread_limit->down();
$thd[$c]=threads->create("sg_ana",$c-1,$c,$num1);
$thd[$c]->detach();
}
&waitquit;
#-------------------------------------------------------------#limite threads num
sub waitquit
{
print "waiting\n";
my $num=0;
while($num<3)
{
$thread_limit->down();
$num++;
}
}
#---------------------------------------------------------------#alignment
my $n;
my $n1;
my $j;
my $k;
my $l;
my $m;
my $num;#number of match
my $num2=0;;#arrange num
sub sg_ana
{
my $c1=shift;
my $c2=shift;
$num1=shift;
open OUT,">$num1.$c2.txt" or die "$!";
if($num1==1)
{
foreach $n($c1*10000..$c2*10000-1)
{
if($spacer2[$n][1])
{
my $presult1;
my $presult2;
$num2=-1;
foreach $i(0..19)
{
$num=0;
$num2++;
my $tmp1=(substr $spacer2[$n][1],0,$i)."\"."w".(substr $spacer2[$n][1],$i+1,19-$i);
foreach $n1(0..@spacer1-1)
{
if($spacer1[$n1][1])
{
my $tmp2=substr $spacer1[$n1][1],0,20;
if($tmp2=~/$tmp1/)
{
$num++;
$presult1.=$n1.",";
}
}
}
$presult2=$i+1;
if($num>=4)
{
print OUT "\n";
}
}
}
}
}
close OUT;
$thread_limit->up();
}
- 调试 perl 的规则一是启用
use strict;
和use warnings;
,然后整理错误。其实你应该 可能首先要这样做,甚至在您开始编写代码之前。 - 您正在通过信号量创建和限制线程 - 但实际上
这真的很低效,因为
perl
如何处理线程 - 它们 不是轻量级的,所以产生负载是个坏主意。更好的方法是通过Thread::Queue
a bit like this. - 请使用 3 个 arg 打开和词法文件句柄。例如
open ( my $out, '>', "$num.$c2.txt" ) or die $!;
。你可能会得到 在这里去掉它,但是你有OUT
作为全局命名空间 变量被多个线程使用。那边有龙。 不要使用单字母变量。考虑到你如何使用
$c
那么你会 远 更好:foreach my $value ( 1..$cycl ) { ## do stuff }
所有 other 单字母变量也是如此 - 它们没有意义。
你在初始化之前传递
$num
,所以它总是 在你的子中undef
。所以你的实际子程序只是:sub sg_ana { my $c1=shift; my $c2=shift; $num1=shift; open OUT,">$num1.$c2.txt" or die "$!"; close OUT; $semaphore->up(); }
看看它 - 我认为您 可能 正在尝试使用那里的共享变量做一些事情,但您实际上并没有共享它。我无法解码你程序的逻辑(由于很可能有大量的单字母变量)所以我不能肯定地说。
- 您正在调用子程序
&waitquit;
。那不是好风格- 以&符号为前缀并且不提供任何参数 与仅调用 sub 'normally' 略有不同 - 所以 你应该避免它。 不要像这样实例化你的信号量:
my $semaphore=new Thread::Semaphore(3);
这是一个间接过程调用,风格很差。最好写成:
my $thread_limit = Thread::Semaphore -> new ( 3 );
我建议不要像那样使用信号量,你最好不要
detatch
使用你的线程,只使用join
。您也不需要线程数组 -threads -> list
会为您完成。我无法重现你的问题,因为你的潜艇没有做 任何事物。您是否有机会修改它以供发布?但是线程化时 perl 内存耗尽的一个典型原因是因为每个线程都克隆父进程 - 因此 100 个线程是内存的 100 倍。