ForkManager (Perl) завершает родительское задание до того, как дочерние задания будут готовы - PullRequest
0 голосов
/ 03 октября 2018

У меня есть следующий код perl:

use Parallel::ForkManager;
  my $maxpro = 15;
  my $pm = Parallel::ForkManager->new($maxpro);
my $SampId;
my $SampDir;
my $RunId;
my $Runfile;
my %hash;
 foreach $RunId(keys(%hash)) {
 $pm->start and next;
 $SampId = $hash{$RunId};
 $Runfile = $rundir . $RunId . "fastq";

 if ($SampId =~ m/16S/) {
     $SampDir = $SiXSSdir . $SampId . "_Split/"; 
 }
 elsif ($SampId =~ m/ITS/) {
     $SampDir = $ITSdir . $SampId . "_Split/";
 }
 #make a directory for each file
 my $dirouteach = $outdir . $SampId . "Single_directory.out";
 my $dirm4 = "bsub -o $dirouteach mkdir $SampDir";

 system('bash', '-c', "$dirm4") == 0 or die "Can't create each single subdirectories for either 16S or ITS, or both, see line 114" . "\n";
$pm ->finish;
}

$pm -> wait_all_children();

Однако, когда я запускаю его таким образом, все дочерние проекты выполняются, но основной сценарий завершается преждевременно, даже до того, как дочерние объекты завершены, онтакже не выдает никаких сообщений об ошибках.Я также попытался запустить его, удалив $pm ->finish;, но в этом случае сценарии застряли и ждут, пока дети не закончат.Я уверен, что я делаю что-то не так с менеджером вилок (который я никогда не использовал раньше).Моей целью было бы просто использовать его для распараллеливания моих заданий, но затем подождать, пока ВСЕ из них будут завершены, и затем перейти к моему сценарию.Любая помощь будет высоко ценится, спасибо!

Ответы [ 2 ]

0 голосов
/ 03 октября 2018

bsub уже является частью платформы для параллельных вычислений.Сама команда bsub выполняется быстро;он просто отправляет задание в планировщик заданий и завершает работу.Он не должен ждать завершения запланированного задания, поэтому все ваши дочерние процессы должны завершиться быстро, и основная программа тоже быстро завершится.

Если вы хотите самостоятельно управлять параллельной обработкой,Вы должны выполнить каждую команду без bsub.Если вы используете bsub, то вам не нужно делать свою собственную разветвленность или использовать диспетчер фоновых процессов, например Parallel::ForkManager.

0 голосов
/ 03 октября 2018

У меня нет идей для отладки Parallel :: ForkManager, но вот пример использования IO :: Async , который немного более гибок, и в то же время обеспечивает хорошую оболочку для необработанных fork и waitpid.

use strict;
use warnings;
use IO::Async::Loop;
use Future;

my $loop = IO::Async::Loop->new;
my @futures;
my %hash;
... # populate %hash
foreach my $RunId (keys %hash) {
  my $dirm4;
  ... # build $dirm4
  my $future = $loop->new_future;
  my $process = $loop->open_process(
    command => ['bash', '-c', $dirm4],
    on_finish => sub { $future->done(@_) },
    on_exception => sub { $future->fail(@_) },
  );
  push @futures, $future;
}

# run event loop until all the futures are done, or throw an exception if one fails to start the command
my @exit_codes = Future->needs_all(@futures)->get;

Вы также можете использовать Future :: Utils для реализации очереди, если вы не хотите запускать их все сразу, я только недавно написал пример в thisответить .

...