我需要帮助将嵌套的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 ....
}
}
}
有没有办法可以将第一个循环分割成如下并且并行运行
#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 ....
}
}
}
如何并行运行每个程序,然后仅在所有子程序Job1,Job2和job3完成时退出主程序。
答案 0 :(得分:6)
我会提供之前使用的similar answer的参考资料 - 他们的关键问题是 - 您的工作是否完全脱离了?例如。没有数据需要在它们之间移动?
如果是这样,请使用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();
对于$i
的每次迭代,这将代码并且并行运行 - 而ForkManager
会将并发性限制为10。
这个数字应该与你的并行性的限制因素大致相当 - 如果是CPU,那么CPU的数量,但请记住,你经常受到磁盘IO的限制。
进行并行时的主要注意事项:
您无法保证执行顺序而不会搞乱。循环$i==1
之后循环$i==2
完全可能完成。或之前。管他呢。
如果您在循环之间传递信息,并行会失去效率 - 因为发送者和接收者都需要同步。如果你需要同步整个批次会更糟,所以尽量避免这样做。 (例如,尽可能将其保留至结束并整理结果)。
对于分叉代码而言,它是双倍的 - 它们是独立的进程,因此您实际上必须尝试来回传输内容。
由于第一点,您可以从并行代码中获得一些非常果味的错误。各行代码可能以任何顺序出现,因此可能会发生非常奇怪的事情。每个进程将进行排序,但多个进程可能会交错。像open ( my $file, ">>", $output_filename );
这样无害的东西会让你失望。
分叉的能力非常有限,它能够在分叉之间共享数据。如果您需要做很多事情,请考虑使用线程。
线程是并发的另一种模式,在某些情况下可能很有价值。我一般都倾向于{{1}一般的“更好”,但在我想要进行相当多的进程间通信的地方,我&#39; d倾向于更多地关注fork
。
Perl daemonize with child daemons