2016-11-24 66 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