以下是我在Perl中的代码的一小段摘录。我收到了错误
错误:使用未初始化的值$ key
但不知道为什么。内部for循环内的$key
更改,但我无法访问外部的值。谁能告诉我我做错了什么?
#!/usr/bin/perl -w
use strict;
use warnings;
use Parallel::ForkManager;
use Cwd;
my $MAX_PROCESSES=16;
print(cwd);
print "\n";
my $num_args = $#ARGV + 1;
if ($num_args < 2) {
print "\nUsage: rot_align_spider.pl <folder containing particles> <reference>\n";
exit;
}
my $folder_name=$ARGV[0];
my $ref=$ARGV[1];
print "Input, $folder_name $ref\n";
system('rm -r rot_align_spider');
system('mkdir rot_align_spider');
my $mv_cmd="cp $folder_name/*.app rot_align_spider";
system($mv_cmd);
system("cp $ref rot_align_spider");
chdir "rot_align_spider";
my @files=`ls *.app`;
#print "@files";
print (cwd);
print "\n";
foreach (@files) {
chomp($_);
#print "$_\n";
my $new_name=$_;
#print "$new_name\n";
$new_name=~s/\.app$//g;
my $rename_files_cmd="mv $_ $new_name";
print "Renaming file $_ to $new_name\n";
system($rename_files_cmd);
}
my $ref_vol=substr($ref,0,-4);
my $new_ref_vol=$ref_vol."_iter_0";
my $ref_cp_cmd="cp $ref $new_ref_vol.spi";
system($ref_cp_cmd);
@files=`ls "$folder_name"*.spi`;
for(my $i=0;$i<1;$i++) {
my $pm=new Parallel::ForkManager($MAX_PROCESSES);
my $ref_id=$i+1;
my $key; #$key defined here
my $j;
for($j=0;$j<scalar(@files);$j++) {
my $pid=$pm->start and next;
chomp($files[$j]);
my $base_name=substr($files[$j],0,-4);
#print "$base_name\n";
my $soc_file_name=$base_name.".soc";
#print "$soc_file_name\n";
my $exp_vol=substr($files[$j],0,-4);
my $aligned_exp_vol=$exp_vol."_iter";
my $ref_vol=substr($ref,0,-4);
$key=$j+1;
open SOC,">$soc_file_name" || die "Can't open file: $!";
print SOC <<EOF;
MD
RESULTS OFF
MD
FBS ON
OR 3Q [phi],[the],[psi],[cc]
$exp_vol
$new_ref_vol
29
0,0,0
SD $key,[phi],[the],[psi],[cc]
cc2n_spider
SD E
ROT
$exp_vol
$aligned_exp_vol
[phi],[the],[psi]
F
U
END
EOF
close SOC;
my $spider_cmd="spider_linux_mp_intel64 soc\/spi \@$base_name";
print "$spider_cmd\n";
system($spider_cmd);
print "$key\n"; #$key printed here in the inner-loop
$pm->finish;
}
#$key=$j;
$pm->wait_all_children;
print "$ref_id $key\n"; #$key printed here in the outer-loop
my $avg_soc_file_name=$folder_name.".soc";
$new_ref_vol=$ref_vol."_iter_".$ref_id;
open SOC,">$avg_soc_file_name" || die "Can't open file: $!";
print SOC <<EOF;
MD
RESULTS OFF
MD
FBS ON
AS S
${folder_name}_bin4x_***_iter
1-$key
A
$new_ref_vol
END
EOF
close SOC;
my $spider_cmd="spider_linux_mp_intel64 soc\/spi \@$folder_name";
print "$spider_cmd\n";
system($spider_cmd);
}
运行后的日志文件 -
**** SPIDER NORMAL STOP ****
28
**** SPIDER NORMAL STOP ****
24
**** SPIDER NORMAL STOP ****
25
**** SPIDER NORMAL STOP ****
29
**** SPIDER NORMAL STOP ****
32
**** SPIDER NORMAL STOP ****
31
**** SPIDER NORMAL STOP ****
33
**** SPIDER NORMAL STOP ****
34
**** SPIDER NORMAL STOP ****
35
**** SPIDER NORMAL STOP ****
36
**** SPIDER NORMAL STOP ****
38
**** SPIDER NORMAL STOP ****
39
**** SPIDER NORMAL STOP ****
41
**** SPIDER NORMAL STOP ****
42
**** SPIDER NORMAL STOP ****
40
**** SPIDER NORMAL STOP ****
37
Use of uninitialized value $key in concatenation (.) or string at ../../rot_align_spider.pl line 104.
Use of uninitialized value $key in concatenation (.) or string at ../../rot_align_spider.pl line 108.
1
答案 0 :(得分:0)
内部循环中的第一行中有一个next
,主进程在每个start
调用之后执行(因为在主进程start
中返回非零的PID孩子;我猜它返回-1
如果它不能start
像系统级fork
那样,那么$key
在主线程中仍未定义通过循环。
此外,您无法在分叉进程中设置$key
并在父进程中进行更改:它们是没有共享数据的单独进程。您可以使用Parallel::ForkManager的finish
方法的第二个参数从子项和run_on_finish
发回数据以收集数据。有关详细信息,请阅读模块文档的RETRIEVING DATASTRUCTURES from child processes部分。
最后,你可能只有16个孩子,因为$MAX_PROCESSES
是16,而wait_all_children
在循环结束之前不会发生;在调用wait_for_available_procs();
之前在循环中添加start
应该有帮助。