[英]How can I modify my perl script to use multiple processors?
嗨,我有一個簡單的腳本,它接受一個文件,並在其上運行另一個Perl腳本。 該腳本對當前文件夾中的每個圖片文件執行此操作。 這是在一台配備2個四核Xeon處理器,16GB內存,運行RedHat Linux的機器上運行的。
第一個腳本work.pl基本上調用magicplate.pl傳遞一些參數和magicplate.pl文件的名稱來處理。 Magic Plate需要大約一分鍾來處理每個圖像。 因為work.pl正在執行相同的功能超過100次,並且因為系統有多個處理器和核心,所以我正在考慮將任務拆分,以便它可以並行運行多次。 如有必要,我可以將圖像分割到不同的文件夾。 任何幫助都會很棒。 謝謝
這是我到目前為止:
use strict;
use warnings;
my @initialImages = <*>;
foreach my $file (@initialImages) {
if($file =~ /.png/){
print "processing $file...\n";
my @tmp=split(/\./,$file);
my $name="";
for(my $i=0;$i<(@tmp-1);$i++) {
if($name eq "") { $name = $tmp[$i]; } else { $name=$name.".".$tmp[$i];}
}
my $exten=$tmp[(@tmp-1)];
my $orig=$name.".".$exten;
system("perl magicPlate.pl -i ".$orig." -min 4 -max 160 -d 1");
}
}
您應該考慮不為要處理的每個文件創建一個新進程 - 這非常低效,而且可能需要花費大部分時間在這里。 只是加載Perl和你一遍又一遍使用的任何模塊應該會產生一些開銷。 我記得PerlMonks上的一張海報做了類似的事情,最后將他的第二個腳本轉換成了一個模塊,將工作時間從一小時縮短到幾分鍾 。 並不是說你應該期待如此顯着的改善,但人們可以夢想......
將第二個腳本重構為模塊, 這是一個線程使用示例 ,其中BrowserUK創建一個線程池,通過隊列為其提供作業。
您可以使用Parallel :: ForkManager(將$ MAX_PROCESSES設置為同時處理的文件數):
use Parallel::ForkManager;
use strict;
use warnings;
my @initialImages = <*>;
foreach my $file (@initialImages) {
if($file =~ /.png/){
print "processing $file...\n";
my @tmp=split(/\./,$file);
my $name="";
for(my $i=0;$i<(@tmp-1);$i++) {
if($name eq "") { $name = $tmp[$i]; } else { $name=$name.".".$tmp[$i];}
}
my $exten=$tmp[(@tmp-1)];
my $orig=$name.".".$exten;
$pm = new Parallel::ForkManager($MAX_PROCESSES);
my $pid = $pm->start and next;
system("perl magicPlate.pl -i ".$orig." -min 4 -max 160 -d 1");
$pm->finish; # Terminates the child process
}
}
但正如Hugmeir所建議的那樣,為每個新文件一次又一次地運行perl解釋器並不是一個好主意。
所有這些都圍繞創建多個工作人員,每個工作人員可以在自己的cpu上運行。 某些實現將更好地使用資源(那些不啟動新進程的資源)並且更易於實現和維護。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.