我编写了一个永久作为守护进程运行的Perl脚本。
my $CHILD_THREADS_CNT=5;
my $q= new Thread::Queue();
sub processJob{
while (defined(my $taskHandle = $q->dequeue()) ) {
my $obj=jobProcesser->new();
my $result=$obj->getOutput(taskHandle);
#jobProcessor is the large modules that computes/manipulates the job
//MySql Query to insert '$result' into DB
}
}
#Daemon subroutine
sub daemon{
while (1){
my @new_request= #'My SQL Queries that returns all new requests from db'
for (@new_request){
$q->enqueue($_);
}
sleep 5;
}
}
#Main thread scans the db, and, enqueue the new job in a queue.
my $scanDB=threads->create(\&daemon);
#children perform processing
my @child=map threads->create(\&processJob), 1..CHILD_THREADS_CNT;
$scanDB->join;
$q->enqueue(undef) for 1..CHILD_THREADS_CNT;
for (@child){
$_->join;
}我使用nohup在unix(Perl v5.8.8)中运行这个脚本。剧本每隔4-5天就会死一次。没有hup不捕获解释脚本突然死亡的原因的日志(主进程)。我预见到内存泄漏,并使用顶级-p PID来分析nohup过程。
随着脚本的持续和永久运行,VIRT(虚拟内存)和RES内存大小不断增长。仅在10小时内就达到了2GB左右的水平。
本质上,一旦子线程完成作业(Process),即。returns $result,那么内存应该已经被释放到操作系统了。
任何帮助都是非常感谢的。
发布于 2014-11-11 11:10:13
正如评论中提到的,这里没有明显的漏洞。
通过从队列中运行'worker‘线程,您已经避免了线程编程中的一些关键“问题”。
我建议您查看一下数据库调用和在processJob子中创建对象时发生了什么。OO中的常见陷阱是在对象内创建循环引用,因此即使对象超出作用域,参考计数也不会降到零。
如果调用析构函数,则可能值得检查。(http://perldoc.perl.org/perlobj.html#Destructors)
DESTROY {
my ( $self ) = @_;
warn $self . " object destroyed";
}https://stackoverflow.com/questions/26862768
复制相似问题