Multithreading 如何在perl中将嵌套for循环转换为多线程程序
我需要帮助将嵌套for循环转换为Perl中的多线程程序,例如Multithreading 如何在perl中将嵌套for循环转换为多线程程序,multithreading,perl,Multithreading,Perl,我需要帮助将嵌套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 .... } } } 对于(my$i=0;$i我将提供一个我以前使用过的示例-关
for ( my $i=0; $i<100; $i++) {
for ( my $j=0; $j<100; $j++ ) {
for ( my $k=0; $k<100; $k++ ) {
#do something ....
}
}
}
对于(my$i=0;$i我将提供一个我以前使用过的示例-关键问题是-您的作业是否完全解耦?例如,无需在它们之间移动数据
如果是这样的话,请使用下面的代码:
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();
使用Parallel::ForkManager;
我的$fork#u manager=Parallel::ForkManager->new(10);#10并行
对于(我的$i=0;$i开始和下一步;
对于(my$j=0;$j<100;$j++){
对于(my$k=0;$k<100;$k++){
#做点什么。。。。
}
}
$fork_manager->finish;
}
$fork_manager->wait_all_children();
对于$i
的每次迭代,这将分叉代码并并行运行,ForkManager
将并发限制在10
这个数字应该与并行性中的限制因素大致相当——如果是CPU,则是CPU的数量,但请记住,您通常更受磁盘IO的限制
执行并行时的关键注意事项:
- 你不能保证执行顺序不乱。完全有可能循环
$i==1
在循环$i==2
之后或之前完成。或者其他任何情况
- 如果您在循环之间传递信息,并行会失去效率-因为发送方和接收方都需要同步。如果您需要同步整批信息,则情况会更糟,因此尽量避免进行不必要的同步(例如,尽可能将其留到最后并整理结果)
- 对于分叉代码来说,这是双重的——它们是独立的进程,所以您实际上必须尝试来回传输东西
- 由于第一点,您可以从并行代码中得到一些非常有用的bug。代码的各行可能以任何顺序出现,因此可能会发生非常奇怪的事情。每个进程都会按顺序进行,但多个进程可能会交错。一些无害的东西,如
open(my$file,“>>”,$output\u filename);
会把你绊倒的
<> > Pr>在叉之间共享数据的能力是非常有限的。如果需要做很多事情,请考虑线程代替。
线程是一种可选的并发模式,在某些情况下可能很有价值。我通常倾向于fork
ing通常“更好”,但在我希望进行相当多的进程间通信的地方,我倾向于更多地关注线程。
循环执行块是相互依赖的吗?还是顺序无关紧要?例如,如果在i=3的块之前执行i=5的块,这对您有关系还是相同?这个问题直接影响解决方案,我会选择Parallel::ForkManager
,因为这看起来是隐式并行的。我可以按任何顺序运行循环只有它们才能成功运行,然后只有主程序才能退出上面的10个实例,i值从1到100,如果我想分割循环,使每个作业实例都以1到10,10到20,20到30,30到40…的值运行,直到100。它将在每次迭代中启动一个实例。因此,最初-10个作业,1..10。作为其中之一完成后,它将从11开始。这样您就可以按顺序处理它们,但始终有10个同时进行。如果您真的想分割它们,那么每个分支都会执行1..10、11..20等操作。您可以,但您需要更改循环。我想问您为什么需要费心,因为创建分支流程是高效的。
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();