PERL脚本提示:Out of memory: Killed process,这是什么问题?

时间:2021-11-08 20:52:38
下面是我的PERL多线程脚本,执行该脚本CPU占用很大,有时候会出现:Out of memory: Killed process,该脚本进程会被自动杀掉,大家帮忙看看这是什么原因造成的,应该怎么做?谢谢!!!!(注:我读的文件只有几条记录)

#!/usr/bin/perl -w 
use strict;
use POSIX qw(strftime);
use FileHandle;
use Fcntl ':flock';
use threads;
use threads::shared;
use Thread::Queue;

chdir("/var/www/sms");

my $r;
my %rq;
my $writelog;
my $writemtreq;
my $i=0;
my $Q = Thread::Queue->new();
my $logqueue=Thread::Queue->new();
my $mtreqqueue=Thread::Queue->new();

open(LOCK,"> ./add_beiweimoto_newlog.lock");
if (flock(LOCK,LOCK_EX|LOCK_NB) == 0)
{
printf "another program is in running! exit now!!!\n";
exit;
}

my %mobareaarr;
open(FILE,"</var/www/sms/conf/mobarea.conf");
while(<FILE>)
{
chomp($_);
$_=~s/[\r\n]//g;

my @vars=split(/\t/,$_);

my $key=substr($vars[0],0,7);
$mobareaarr{$key}={"area"=>$vars[1],"areaname"=>$vars[2],"areadetail"=>$vars[3]};
}
close(FILE);



$r=threads->create(\&read_file,'/var/www/appserver/log/beiwei_mo_');

for($i=1;$i<=10;$i++){
$rq{$i}=threads->create(\&read_queue_thread);
}

$writelog=threads->create(\&write_log);

while(1){
my $res1=$r->join();
for($i=1;$i<=10;$i++)
{
$rq{$i}->join();
}
$writelog->join();
  last;
}


my $curtime  = strftime "%Y%m%d",localtime(time);

sub read_file()
{
my $filehead = shift;
my $filehand = new FileHandle;
#my $curtime  = strftime "%Y%m%d",localtime;
my $curtime  = strftime "%Y%m%d",localtime(time);
my $logtail  = "";
my $filename = "";
my $buf      = "";
my $cfgfile  = $filehead."log.$curtime.cfg";
my $_init=1;
my $_curline=0;
my $_oldline=0;
my $cfghandle=new FileHandle;
if(-e $cfgfile)
{
$cfghandle->open($cfgfile, "r+");
$_oldline=$cfghandle->getline;
if(defined($_oldline))
{
$_oldline=int($_oldline);
}
}
else
{
$cfghandle->open($cfgfile, "w+");
}
if(defined($cfghandle))
{
$cfghandle->autoflush(1);
}

while(1){
#$curtime= strftime "%Y%m%d",localtime;
$curtime  = strftime "%Y%m%d",localtime(time);
if($logtail ne $curtime )
{
$logtail=$curtime;
$filename=$filehead.$logtail.".log";
if(-e $filename){
$filehand->close;
$filehand->open("< $filename");
$filehand->autoflush(1);
}else
{
sleep(5);
$logtail="";
print "next\n";
next;
}
$_curline=0;
}

while(defined($buf=$filehand->getline))
{
$_curline++;
if($_init)
{
if($_curline <= $_oldline)
{
next;
}
}
$_init=0;
$cfghandle->seek(0,0);
truncate($cfghandle,0);
print $cfghandle $_curline;

$buf=substr($buf,0,length($buf)-1);
$Q->enqueue($buf);
$buf="";
}

sleep(5);
}
return 1;
}


sub read_queue_thread()
{
my $curtime  = strftime "%Y%m%d",localtime(time);
my $buf="";
my $logtime="";
my $recvtime="";
my $spid="";
my $spcode="";
my $srctermid="";
my $toicp="";
my $feeprice=0;
my $feetype="";
my $product="";
my $feecategory="";
my $channel="";
my $linkid="";
my $simulate="";
my $format="";
my $content="";
my $isprovision="";
my $issubscribe="";
my $node="";
my $area="";
my $areaname="";
my $areadetail="";
my $realcompanyid="";
my $companyid="";
my $subcompanyid="";
my $createDate="";
my $msg="";

while(1)
{
$buf = $Q->dequeue;

if(defined($buf))
{
if($buf=~/([^\|]*)\|([^\|]*)\|([^\|]*)\|([^\|]*)\|([^\|]*)\|([^\|]*)\|([^\[]*)\[([^\]*)\]\|([^\|]*).*/i)
{

$feecode=$1;
$srctermid=$2;
$spcode=$3;
$toicp=substr($spcode,4,(length($spcode)-4));
$linkid=$4;
$content=$5;

$logtime=substr($7,0,4)."-".substr($7,4,2)."-".substr($7,6,2)." ".substr($7,8,2).":".substr($7,10,2).":".substr($7,12,2);
$createDate=substr($8,0,4)."-".substr($8,4,2)."-".substr($8,6,2)." ".substr($8,8,2).":".substr($8,10,2).":".substr($8,12,2);
$feeprice=$9;

$content=~s/\\/ /g;
$content=~s/\'/ /g;

my $key = substr($srctermid,0,7);

$area=$mobareaarr{$key}->{"area"}; 
$areaname=$mobareaarr{$key}->{"areaname"}; 
$areadetail=$mobareaarr{$key}->{"areadetail"};

if($content =~ /^6922([0-9]{3})(.*)/i)
{
$companyid=$1;
$realcompanyid=$1;
$subcompanyid=$1;
}

$spid="cmcc-$toicp";
$node="";
$feetype="ITEM";
$product="";
$feecategory="null";
$channel="";
$simulate="";
$format="";
$isprovision="";
$issubscribe="";
$msg="6922";

my $logstr="[$logtime]\tspid[$spid]\tspcode[$spcode]\ttoicp[$toicp]\tnode[$node]\tfeecode[$feecode]\tfeeprice[$feeprice]\tfeetype[$feetype]\tproduct[$product]\tfeecategory[$feecategory]\tchannel[$channel]\tmobile[$srctermid]\tlinkid[$linkid]\tsimulate[$simulate]\tformat[$format]\tcontent[$content]\tisprovision[$isprovision]\tissubscribe[$issubscribe]\tcreateDate[$createDate]\tarea[$area]\tareaname[$areaname]\tareadetail[$areadetail]\trealcompanyid[$realcompanyid]\tcompanyid[$companyid]\tsubcompanyid[$subcompanyid]\tmsg[$msg]\n";

$logqueue->enqueue($logstr);

}
}
}
return 1;
}



sub write_log()
{
my $logname="/var/www/appserver/log/lognew/beiwei_mo_new.";
my $buf="";
#my $time=strftime "%Y%m%d",localtime;
my $time=strftime "%Y%m%d",localtime(time);
my $logtail="";
my $filehand = new FileHandle;
while(1)
{
$time=strftime "%Y%m%d",localtime(time);
#$time=strftime "%Y%m%d",localtime;
if($time ne $logtail)
{
$logtail=$time;
$filehand->close;
$filehand->open(">>".$logname.$logtail.".log");
$filehand->autoflush(1);
}
$buf=$logqueue->dequeue;
if(defined($buf))
{
print $filehand $buf;
print "buf:$buf\n";
$buf="";
}
}

}

11 个解决方案

#1


对perl多线程的建议就是:别用多线程。

#2


不是吧?多线程就会出现这个问题吗?

#3


原因我不清楚,只是建议不用多线程。
有些版本下的perl 多线程 不稳定。

#4


Perl的多线程是问题比较多。看你要解决什么问题了,或许可以考虑POE。不过POE嘛,虽然有些人赞不绝口,我是感觉有点反人性。

#5


引用 4 楼 iambic 的回复:
Perl的多线程是问题比较多。看你要解决什么问题了,或许可以考虑POE。不过POE嘛,虽然有些人赞不绝口,我是感觉有点反人性。

我对你说的反人性很感兴趣,能不能详细说说你的感觉?

#6


我是来打酱油的~~

#7


学习中

#8


反人性?怎么说?

#9


什么是反人性啊。。。

#10


内存占用太多?

#11


POE是一个事件驱动的框架,有自己的规则。你的程序,每一个部分,不管是什么逻辑,都需要完全按照他的规则来设计。导致很多简单而基本的东西需要很让人无语的方式来完成,或者很难完成,比如父子*要通信。写一个POE*也是比较麻烦的事情。另外POE在Windows上很容易崩溃,特别是和其他模块一起使用的时候。有时候只要一个简单的use就崩溃了。

#1


对perl多线程的建议就是:别用多线程。

#2


不是吧?多线程就会出现这个问题吗?

#3


原因我不清楚,只是建议不用多线程。
有些版本下的perl 多线程 不稳定。

#4


Perl的多线程是问题比较多。看你要解决什么问题了,或许可以考虑POE。不过POE嘛,虽然有些人赞不绝口,我是感觉有点反人性。

#5


引用 4 楼 iambic 的回复:
Perl的多线程是问题比较多。看你要解决什么问题了,或许可以考虑POE。不过POE嘛,虽然有些人赞不绝口,我是感觉有点反人性。

我对你说的反人性很感兴趣,能不能详细说说你的感觉?

#6


我是来打酱油的~~

#7


学习中

#8


反人性?怎么说?

#9


什么是反人性啊。。。

#10


内存占用太多?

#11


POE是一个事件驱动的框架,有自己的规则。你的程序,每一个部分,不管是什么逻辑,都需要完全按照他的规则来设计。导致很多简单而基本的东西需要很让人无语的方式来完成,或者很难完成,比如父子*要通信。写一个POE*也是比较麻烦的事情。另外POE在Windows上很容易崩溃,特别是和其他模块一起使用的时候。有时候只要一个简单的use就崩溃了。