2016-11-24 63 views
0

我在多线程中运行Perl脚本时遇到了麻烦。它继续消耗内存,最终系统耗尽内存并杀死它。看起来子线程已经分离,但是系统资源在完成时没有被释放。我对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=$1; 
     $spacer1[$no][0]=$3;   
     } 
    else 
     { 
     $spacer1[$no][1]=$_;  
     } 
    } 
close IN; 

open IN, "file2.txt" or die "$!"; 
    while(<IN>) 
    { 
    chomp; 
    if($_=~ /^>((\d)+)\|((\d)+)/) 
     {   
     $nn=$1; 
     $spacer2[$nn][0]=$3;  
     } 
    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([email protected]) 
         { 
         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(); 
    } 
+0

这是你的整个代码?你的'$ num1'永远不会被定义,这使'sg_ana'的子例程几乎成为空操作。 (这是'使用警告'会警告你的) – oals

+0

这只是代码的一部分。在这部分之前,它从文件中读取。我相信这部分没有问题。 – c11cc

+0

您编辑的代码仍然有语法错误。 [mcve]在这里会有所帮助。 – Sobrique

回答

0
  1. 规则调试的perl之一是使use strict;use warnings;,然后整理出错误。实际上,在开始编写代码之前,您应该首先做到这一点。
  2. 你正在通过信号量来创建和限制线程 - 但实际上这是因为perl线程的效率非常低,它们不是轻量级的,所以产卵负载是一个坏主意。更好的方法是通过Thread::Queuea bit like this.
  3. 请使用3个arg开放和词法文件句柄。例如open (my $out, '>', "$num.$c2.txt") or die $!;。您可能在这里得到了 ,但您已将OUT作为全局命名空间 变量被多个线程使用。龙就是这样。
  4. 请勿使用单个字母变量。并给予你如何使用$c 那么你会更好:

    foreach my $value (1..$cycl) { 
        ## do stuff 
    } 
    

同样是所有其他单个字母的变量,虽然真正的 - 他们是没有意义的。

  • 你传递$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;。这是不好的风格 - 前缀与&符号,并提供没有参数 东西有点不同,只是调用子'正常' - 所以 你应该避免它。
  • 不要实例化你的信号是这样的:

    my $semaphore=new Thread::Semaphore(3); 
    
  • 这是一个间接的过程调用和不良作风。这将更好的写法如下:

    my $thread_limit = Thread::Semaphore -> new (3); 
    
  • 我会建议,而不是使用信号灯那样,你会好得多detatch荷兰国际集团的线程,只是使用join。你也不需要一组线程 - threads -> list为你做。

  • 我不能重现你的问题,因为你的子没有做任何事情 。你有没有可能修改它发布?但是,线程化时perl内存耗尽的一个典型原因是因为每个线程都克隆了父进程 - 所以100个线程是内存的100倍。

  • +0

    非常感谢。它确实有帮助。 – c11cc

    +0

    1.在本部分之前使用严格和警告,因为我确信该部分是好的,所以我只是没有发布它们。 – c11cc

    +0

    2我注意到OUT在线程中使用,但我不知道如何处理它。我会尽力改变它。 – c11cc