Domanda

Ciao ho un semplice script che prende un file e viene eseguito un altro script Perl su di esso. Lo script fa questo a tutti i file di immagine nella cartella corrente. Questo è in esecuzione su un computer con processori 2 Quad Core Xeon, 16GB di RAM, in esecuzione RedHat Linux.

La prima work.pl script chiama fondamentalmente magicplate.pl passa alcuni parametri e il nome del file per magicplate.pl al processo. Piastra magia richiede circa un minuto per elaborare ogni immagine. Perché è work.pl preformare la stessa funzione oltre 100 volte e perché il sistema dispone di più processori e core pensavo dividere il compito in modo da poter eseguire più volte in parallelo. Potrei dividere le immagini fino a cartelle diverse, se necessario. Qualsiasi aiuto sarebbe grande. Grazie

Ecco quello che ho finora:

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");
     }
}       
È stato utile?

Soluzione

Si potrebbe utilizzare in parallelo :: ForkManager (set $ MAX_PROCESSES al numero di file elaborati allo stesso tempo):

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

     }
}       

Ma, come suggerito da Hugmeir correre di nuovo e di nuovo interprete Perl per ogni nuovo file non è una buona idea.

Altri suggerimenti

Si dovrebbe prendere in considerazione non la creazione di un nuovo processo per ogni file che si desidera elaborare - E 'terribilmente inefficiente, e probabilmente ciò che sta prendendo la maggior parte del vostro tempo qui. Basta caricare fino Perl e tutto ciò che i moduli si utilizza più e più volte dovrebbe essere la creazione di un certo overhead. Ricordo un poster sul PerlMonks che ha fatto qualcosa di simile, e ha finito per trasformare il suo secondo script in un modulo, riducendo il tempo di lavoro da un'ora a un paio di minuti . Non che si dovrebbe aspettare un miglioramento così drammatico, ma si può sognare ..

Con il secondo script riscritta come modulo, qui un esempio di utilizzo di thread , in che BrowserUK crea un pool di thread, alimentandola di posti di lavoro attraverso una coda.

  • Importa "maigcplate" e l'uso threading.
  • Avvia magicplate.pl in background (si avrebbe bisogno di aggiungere la limitazione di processo)
  • Importa "magicplate" e uso forcella (add limitazione di processo e una mietitrice kiddy)
  • Fare "maigcplate" un demone con un pool di lavoratori = # di CPU
    • utilizzare un'implementazione MQ per la comunicazione
    • utilizzare i socket per la comunicazione
  • Usa webserver (nginx, apache, ...) ed avvolgere in riposo per un webservice
  • ecc ...

Tutte queste centro attorno la creazione di più i lavoratori che possono ogni esecuzione per conto proprio cpu. Alcune implementazioni utilizzeranno le risorse migliori (quelli che non iniziano un nuovo processo) ed essere più facile da implementare e mantenere.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top