简体   繁体   English

Perl在并行化后打印嵌套循环输出时出现问题

[英]Perl problems printing nested loop output after Parallelizing

I'm trying to print output of the following code , but there is something wrong with it, some lines do not have 5 columns, some values are missing, mixed , .... 我正在尝试打印以下代码的输出,但是它出了点问题,有些行没有5列,有些值丢失了,混合了....

./script.pl file 5 0.00 0.021 ./script.pl文件5 0.00 0.021

#!/usr/bin/perl

use warnings;
use strict;

use Parallel::ForkManager;

my $outputfilename = $ARGV[0];
my $CPU_count      = $ARGV[1];
my $start          = $ARGV[2];
my $end            = $ARGV[3];


my $fork_manager = Parallel::ForkManager->new($CPU_count);

for ( my $k1 = $start; $k1 < $end; $k1 += 0.001 ) {

    $fork_manager->start and next;

    for ( my $k2 = $start; $k2 < $end; $k2 += 0.01 ) {
        for ( my $k3 = $start; $k3 < $end; $k3 += 0.001 ) {
            for ( my $k4 = $start; $k4 < $end; $k4 += 0.001 ) {
                for ( my $k5 = $start; $k5 < $end; $k5 += 0.001 ) {

open my $F1, '>',$outputfilename . "_" . $k1 . $k2 . $k3 . $k4 . $k5  or die $!;
         print  $F1 ("k1: $k1\tk2: $k2\tk3: $k3\tk4: $k4\tk5: $k5\n");

                }
            }
        }
    }
    $fork_manager->finish;
}
$fork_manager->wait_all_children;

incorrect output 输出不正确

...
k1: 0.002   k2: 0.00    k3: 0.00    k4: 0.016   k5: 0.006
k1: 0.002   k00 k2: 0.00    k3: 0.001   k4: 0.012   k5: 0.003
k1: 0.003   k2: 0.00    k3: 0.012   k4: 0.013   k5: 0.001
k1: 0.003   k2: 0.00    k3: 0.012   0.011
....

Thank you very much for your help! 非常感谢您的帮助!

Your forks are racing to write to file. 您的分叉正在争分夺秒地写文件。 Depending on what you want from your output, you should place exclusive file locks on strategic points. 根据您要从输出中获得什么,您应该在策略点上放置排他文件锁。

In example below at least lines won't get mixed up. 在下面的示例中,至少行不会混淆。

 use Fcntl qw(:flock);

 # ...
 flock($F1, LOCK_EX) or die $!;
 print $F1 ("k1: ",$k1,"\t","k2: ",$k2,"\t","k3: ",$k3,"\t","k4: ",$k4,"\t","k5: ",$k5,"\n");
 flock($F1, LOCK_UN);
for ( my $k1 = $start; $k1 < $end; $k1 += 0.001 ) {

    $fork_manager->start and next;
    open ( my $output, ">", $outputfilename."_".$k1 ) or die $!;
    for ( my $k2 = $start; $k2 < $end; $k2 += 0.01 ) {
        for ( my $k3 = $start; $k3 < $end; $k3 += 0.001 ) {
            for ( my $k4 = $start; $k4 < $end; $k4 += 0.001 ) {
                for ( my $k5 = $start; $k5 < $end; $k5 += 0.001 ) {
                    print  {$output} ("k1: $k1\tk2: $k2\tk3: $k3\tk4: $k4\tk5: $k5\n");
                }
            }
        }
    }
    close ( $output );
    $fork_manager->finish;
}
$fork_manager->wait_all_children;


foreach ( my $filename, glob ( "$outputfilename_*" ) ) {
     #stick together the results of something. 
}

You'll end up with one file per fork - so from 0..1 you'll get 1000. But each fork will have one active output filehandle, so no race condition. 您最终将在每个fork中得到一个文件-因此从0..1您将得到1000。但是每个fork将具有一个活动的输出文件句柄,因此没有竞争条件。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM