- 论坛徽章:
- 0
|
perl新手求助~
创建了N个线程,每个线程执行同样的功能(函数),每个线程从队列中获取数据处理,代码大体框架如下:
my $thread_num = int(sysconf(SC_NPROCESSORS_ONLN));
for (0..$thread_num) {
$data_queue->enqueue(undef);
threads->create(sub {
while (my $pack = $data_queue->dequeue()) {
process($pack);
}
});
}
foreach (threads->list()) { $_->join(); }
其中process函数需要执行外部shell命令,执行shell命令的函数如下:
sub my_system {
my $cmd = shift;
debug("my_system: $cmd");
my $ret;
my $pid;
my @out = ();
if (wantarray) {
defined($pid=open(PIPE, "-|")) or die "Can not fork: $!\n";
} else {
defined($pid=fork) or die "Can not fork: $!\n";
}
unless ($pid) { # Child
open(STDERR, ">&STDOUT");
exec ($cmd);
} else { # Parent
if (wantarray) {
while (my $line = <PIPE>) {
print $line;
push @out, $line;
}
}
waitpid ($pid,0);
$ret = $?;
close(PIPE) if wantarray;
return wantarray ? ($ret, @out): $ret;
}
}
现在的问题是代码运行的时候,经常在my_system里面出现父进程挂住,使用ps可以看到有不少子进程是defunct进程,我的分析是父进程陷入while (my $line = <PIPE>)不能跳出循环。。。
尝试过以下方法:
1. 直接使用系统的system调用,也会出现挂住;
2. 直接使用readpipe,也会挂住;
3. 将线程数改小,挂住的几率会变小,但是时间长了依然会挂住;
4. 在父进程的while 循环里面,加入sleep,几率明显降低,但还是会有(跑了3个多小时出现);
个人觉得是stdout缓存区的问题。。。
求助各位帮忙看看,到底是哪边的问题,如何才能彻底解决?
|
|