Arrays 在信号处理函数(Perl)中从main::更新数组
我想维护一个我已经分叉的子进程的pidlist数组,然后在它们退出时删除它们(以限制在任何给定时间我有多少分叉进程)。我认为我可能很聪明,可以通过在delete或splice中使用@main::pid_列表来实现这一点,但没有乐趣。我可以成功地弹出一个元素,但显然它不会删除正确的pid。有没有办法处理这个问题,或者我最好用完全不同的方式来处理Arrays 在信号处理函数(Perl)中从main::更新数组,arrays,perl,sigchld,Arrays,Perl,Sigchld,我想维护一个我已经分叉的子进程的pidlist数组,然后在它们退出时删除它们(以限制在任何给定时间我有多少分叉进程)。我认为我可能很聪明,可以通过在delete或splice中使用@main::pid_列表来实现这一点,但没有乐趣。我可以成功地弹出一个元素,但显然它不会删除正确的pid。有没有办法处理这个问题,或者我最好用完全不同的方式来处理 #!/usr/bin/perl -w use POSIX ":sys_wait_h"; use Data::Dumper; # Only allow 5
#!/usr/bin/perl -w
use POSIX ":sys_wait_h";
use Data::Dumper;
# Only allow 5 processes running at a time
sub REAPER {
my $child = shift;
while (($child = waitpid(-1, WNOHANG)) > 0) {
# Need to remove child from pidlist here
#pop(@main::pid_list); #This works
#delete($main::pid_list[$child]); #This does not
}
$SIG{CHLD} = \&REAPER;
}
@pid_list = ();
@files = (1 .. 20);
foreach my $file (@files) {
my $processed = 'false';
while ($processed eq 'false') {
print "Working on file: $file\n";
$SIG{CHLD} = \&REAPER;
if (scalar(@pid_list) < 5) {
$pid = fork();
if ( $pid == 0 ) {
print "$$: Child Processing file #" . $file . "\n";
sleep(10);
print "$$: Child done processing file #" . $file . "\n";
exit(0);
}
push(@pid_list, $pid);
print Dumper(@pid_list);
$processed = 'true';
}
sleep(1);
}
}
# Since we are at the end we need to wait for the last process to end
print "PID: $$ End of parent program\n";
exit 0;
#/usr/bin/perl-w
使用POSIX“:sys_wait_h”;
使用数据::转储程序;
#一次只允许运行5个进程
副收割器{
我的$child=shift;
而($child=waitpid(-1,WNOHANG))>0){
#需要在此处从pidlist中删除子项
#pop(@main::pid_list);#这很有效
#删除($main::pid_list[$child]);#这不会
}
$SIG{CHLD}=\&REAPER;
}
@pid_列表=();
@文件=(1..20);
foreach my$文件(@files){
我的$processed='false';
而($processed eq'false'){
打印“处理文件:$file\n”;
$SIG{CHLD}=\&REAPER;
if(标量(@pid_list)<5){
$pid=fork();
如果($pid==0){
打印“$$:子处理文件”#“$文件”。\n”;
睡眠(10);
打印“$$:子处理完成文件”#“$文件”。\n”;
出口(0);
}
推送(@pid_list,$pid);
打印转储程序(@pid_列表);
$processed='true';
}
睡眠(1);
}
}
#因为我们已经结束了,我们需要等待最后一个过程结束
打印“PID:$$End of parent program\n”;
出口0;
试试@main::pid\u list=grep$\ux!=$子级,@main::pid_list代码>试试@main::pid\u list=grep$\ux!=$子级,@main::pid_list代码>使用哈希表而不是数组
sub REAPER {
my $child = shift;
while (($child = waitpid(-1, WNOHANG)) > 0) {
# Need to remove child from pidlist here
delete $main::pid_list{$child};
}
$SIG{CHLD} = \&REAPER;
}
...
if ((scalar keys %main::pid_list) < 5) {
...
if ($pid != 0) {
...
exit(0);
}
$main::pid_list{$pid}++;
}
sub-REAPER{
我的$child=shift;
而($child=waitpid(-1,WNOHANG))>0){
#需要在此处从pidlist中删除子项
删除$main::pid_列表{$child};
}
$SIG{CHLD}=\&REAPER;
}
...
if((标量键%main::pid_列表)<5){
...
如果($pid!=0){
...
出口(0);
}
$main::pid_list{$pid}++;
}
使用哈希表而不是数组
sub REAPER {
my $child = shift;
while (($child = waitpid(-1, WNOHANG)) > 0) {
# Need to remove child from pidlist here
delete $main::pid_list{$child};
}
$SIG{CHLD} = \&REAPER;
}
...
if ((scalar keys %main::pid_list) < 5) {
...
if ($pid != 0) {
...
exit(0);
}
$main::pid_list{$pid}++;
}
sub-REAPER{
我的$child=shift;
而($child=waitpid(-1,WNOHANG))>0){
#需要在此处从pidlist中删除子项
删除$main::pid_列表{$child};
}
$SIG{CHLD}=\&REAPER;
}
...
if((标量键%main::pid_列表)<5){
...
如果($pid!=0){
...
出口(0);
}
$main::pid_list{$pid}++;
}
没有必要在那里使用scalar
,没有必要在那里使用scalar
,看起来是使用Parallel::ForkManager的好地方