如何将嵌套的for循环转换为perl中的多线程程序

use*_*136 5 perl multithreading

我需要帮助将嵌套的for循环转换为Perl中的多线程程序,例如

for ( my $i=0; $i<100; $i++) {
    for ( my $j=0; $j<100; $j++ ) {
         for ( my $k=0; $k<100; $k++ ) { 
             #do something ....                 
         } 
     }
 }
Run Code Online (Sandbox Code Playgroud)

有没有办法我可以分割第一个循环如下并行并行运行它们

#Job1: 
for ( my $i=0; $i < 40; $i++) {
    for( my $j=0; $j < 100; $j++) {
        for( my $k=0; $k < 100; $k++) {
            #do something ....
         }
     }
 }

#Job2: 
for ( my $i=40; $i < 80; $i++) {
    for( my $j=0; $j<100; $j++) {
        for( my $k=0; $k<100; $k++) {
            #do something ....
         }
     }
 }

#Job3
for ( my $i=80; $i < 100; $i++) {
    for( my $j=0; $j < 100; $j++) {
        for( my $k=0; $k < 100; $k++) {
            #do something ....
         }
     }
 }
Run Code Online (Sandbox Code Playgroud)

如何并行运行每个程序,然后仅在所有子程序Job1,Job2和job3完成时退出主程序.

Sob*_*que 6

我将提供一个我以前用过的类似答案的参考- 他们的关键问题是 - 你的工作完全解耦了吗?例如,没有数据需要在它们之间移动?

如果是这样,使用Parallel::ForkManager它有点像这样:

use Parallel::ForkManager;
my $fork_manager = Parallel::ForkManager -> new ( 10 ); #10 in parallel

for ( my $i=0;$i<100;$i++) {
    #in parallel:
    $fork_manager -> start and next;
    for ( my $j=0; $j < 100; $j++) {
         for ( my $k=0; $k < 100; $k++) { 
             #do something ....
         }
    }
    $fork_manager -> finish;
}
$fork_manager -> wait_all_children();
Run Code Online (Sandbox Code Playgroud)

对于$i代码的每次迭代并且并行运行,这将使ForkManager并发性为10.

这个数字应该与你的并行性的限制因素大致相当 - 如果它是CPU,那么CPU的数量,但请记住,你经常受磁盘IO的限制.

做并行时的关键警告:

  • 你无法保证执行顺序而不会搞乱.循环$i==1完成循环后完全有可能$i==2.或之前.管他呢.

  • 如果你在循环之间传递信息,并行会失去效率 - 因为发送者和接收者都需要同步.如果你需要同步整个批次,那就更糟了,所以尽量避免这样做.(例如,尽可能将其保留至结束并整理结果).

  • 对于分叉代码来说这是双倍的 - 它们是独立的进程,所以你实际上必须尝试来回传输事物.

  • 你可以从并行代码中获得一些真正非常果味的错误,因为第一点.各行代码可能以任何顺序出现,因此可能会发生非常奇怪的事情.每个进程都会进行排序,但多个进程可能会交错.像open ( my $file, ">>", $output_filename );你这样无害的东西可以绊倒你.

  • 叉子在叉子之间共享数据的能力非常有限.如果您需要做很多事情,请考虑使用线程.

线程是并发的替代模型,在某些情况下可能很有价值.我通常倾向于fork普遍"更好",但在我想要进行相当多的进程间沟通的地方,我倾向于更多地关注threads. 使用子守护进程进行Perl守护进程