Perl:使用未初始化的值

时间:2015-05-26 14:00:55

标签: perl

以下是我在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

1 个答案:

答案 0 :(得分:0)

内部循环中的第一行中有一个next,主进程在每个start调用之后执行(因为在主进程start中返回非零的PID孩子;我猜它返回-1如果它不能start像系统级fork那样,那么$key在主线程中仍未定义通过循环。

此外,您无法在分叉进程中设置$key并在父进程中进行更改:它们是没有共享数据的单独进程。您可以使用Parallel::ForkManagerfinish方法的第二个参数从子项和run_on_finish发回数据以收集数据。有关详细信息,请阅读模块文档的RETRIEVING DATASTRUCTURES from child processes部分。

最后,你可能只有16个孩子,因为$MAX_PROCESSES是16,而wait_all_children在循环结束之前不会发生;在调用wait_for_available_procs();之前在循环中添加start应该有帮助。