2013-10-03 5 views
0

Итак, у меня возникла проблема с массивом @cpuAll, потерявшим значение после $ pm-> finish. Это просто SSHing на кучу серверов и возвращает некоторые статистические данные, которые отлично работают. Но после завершения последнего цикла массив не будет печататься. Я не хочу писать все в файлы, потому что получаю 90% увеличение производительности, просто загружая его в массив.Perl forkmanager dropping value value

my @cpuAll =(); 
my @memAll =(); 
$pm->run_on_finish(sub{ 
     my ($pid,$exit_code,$ident,$exit_signal,$core_dump,$data)[email protected]_; 
     push(@data,$data); 
}); 
for(@servers) 
{ 
    next if $_ =~ "10.1.4.52"; 
    next if $_ =~ "10.1.4.106"; 
    my $pid = $pm->start and next; 
    chomp; 
    my @output_cpu = `/usr/bin/ssh $_ \"/root/scripts/punkbuster.cpu|sed 's/ (//g'|sed 's/)//g'|sed s'/ //g'\"`; 
    for(@output_cpu) 
    { 
     chomp; 
     my ($server,$username,$cpu,$process)=(split /:/, $_)[0,1,2,3]; 
#  push(@cpuAll,"$server\,$username\,$cpu\,$process\,$date\,$time\n"); 
    } 
$pm->finish(0, [$server,$username,$cpu,$process]); 
} 

print $_ for @data; 
print "OK\n"; 
$pm->wait_all_children; 
+0

Вы добавляете данные в '@ cpuAll' в дочернем процессе, но пытаетесь извлечь его из' @ cpuAll' в родительском процессе. Вам необходимо отправить данные от ребенка родительскому. См. Раздел в документах P :: FM под названием «ВОЗВРАТ ДАТЫСТРУКТУРЫ из дочерних процессов». – ikegami

+0

Но я думал, что с тех пор, как я объявил его за пределами цикла, он будет придерживаться, ваше высказывание, поскольку это совершенно другой процесс, который ему нужно вернуть, чтобы использовать его в родительском процессе. – ThatGuy

+0

Да, изменение переменной в одном процессе не влияет на аналогичные именованные переменные в других процессах. Слава Богу! – ikegami

ответ

2

я столкнулся с подобными проблемами в прошлом, и я верю, что вы найдете решение в документации по data structure retrieval. Вам нужно передать данные для завершения, как $pm->finish(0, \@cpuAll), а затем использовать обратный вызов в $pm->run_on_finish, чтобы перебрать ваш массив и распечатать все, что вам нужно. Представленная мной ссылка показывает пример кода, который должен быть очень четким в том, как извлекать данные. Дайте мне знать, если нет, и я добавлю больше к моему ответу.

+0

Эй, поэтому я сделал что-то вроде этого, но мой run_on_finish не передавал аргументы должным образом. – ThatGuy

+0

Если он по-прежнему не работает для вас, я бы рекомендовал отредактировать сообщение, чтобы мы могли видеть код. Затем мы можем сделать некоторые обоснованные предложения. – SES

+0

Я не знаю, с чего начать. Мне трудно понять, что говорит документация, которую я должен делать. Мне не нужно печатать его, но в конечном итоге добавить все данные из каждого массива, сгенерированного в один массив. – ThatGuy

1

Используйте Net::OpenSSH::Parallel!

my $pssh = Net::OpenSSH::Parallel->new; 
for my $server (@servers) { 
    $pssh->add_host($server); 
} 
$pssh->push(*, cmd => { stdout_file => "%LABEL%.out" }, 
      "/root/scripts/punkbuster.cpu|sed 's/ (//g'|sed 's/)//g'|sed s'/ //g'"); 
$pssh->run; 

my @cpuAll; 
for my $server (@servers) { 
    if (open my $fh, '<', "$server.out") { 
     my ($server,$username,$cpu,$process) = split /:/; 
     push @cpuAll, join ',', (split /:/)[0..3], $date, $time; 
    } 
    else { 
     warn "unable to retrieve data for $server\n"; 
    } 
} 

print "$_\n" for @cpuAll; 

Я хотел бы также заменить sed замены некоторой локальной постобработки сделано в Perl.