Wie man ein perl-Skript in parallel

Wie kann ich ein perl-Skript, parallel mit unterschiedlichen input params jedes mal:

Illustration:

perl example.pl param1 param2
perl example.pl param3 param4

ich möchten, führen Sie das perl-Skript example.pl 2 oder mehrere Male mit unterschiedlichen input –paramsX. Jedes mal sollte es parallel laufen.

Einer Probe algo unter:

my $params='1,2,3,4,5';   
my @all_params = split(/\;/, $params);
foreach my $entry (@all_param)
    {
      perl example.pl $entry
    }

ich möchten, führen Sie das perl-Skript in parallel for each-Schleife.

  • split mit für comma oder semicolon
  • bitten Sie bitte erläutern Sie ein bisschen..
  • perl example.pl $entry statt system("call perl example.pl $entry"). versuchen Sie herauszufinden, einige Informationen in Suchmaschinen.
  • Es gibt viele Möglichkeiten. Vielleicht versuchen Sie es Parallel::ForkManager. Sie müssen lernen, ein bisschen über das, was ist dahinter, aber das kann eine einfachste, um mit zu beginnen. Suche diese Website, es gibt viele viele Beiträge über das, was Sie fordern.
  • Sehen Sie die Leiste mit den links auf der rechten Seite dieser Seite unter Verwandte.
  • Die Abstimmung zu schließen als Duplikat von how-to-call-single-perl-script-to-run-parallely-through-loop-for-different-input

InformationsquelleAutor Yash | 2017-04-18



2 Replies
  1. 2

    Du fragst nach etwas, das scheint ziemlich einfach, aber in Wirklichkeit ist insgesamt komplizierter, als es scheint.

    Es ist nicht allzu schwer zu parallelise in perl, aber … hier werden Drachen. Parallel-code stellt eine ganze Reihe neuer Fehler und race-conditions, da Ihr Programm wird nicht deterministisch. Sie können nicht mehr wissen, die Reihenfolge der Ausführung zuverlässig. (Und wenn Sie übernehmen, dass Sie das tun, erstellen Sie eine race-condition).

    Aber mit dem Gedanken im Kopf – es gibt wirklich 3 (ish?) Wege gehen, gehen Sie über es.

    Gabel

    Verwenden Parallel::ForkManager und schließen Sie die innere Schleife in eine Gabel. Dies funktioniert gut für ‚einfache‘ Parallelismus, aber die Kommunikation zwischen Ihren Gabeln ist schwierig.

    #!/usr/bin/env perl
    
    use strict;
    use warnings;
    
    use Parallel::ForkManager;
    
    my $manager = Parallel::ForkManager->new(2);    #2 concurrent
    
    my $params = '1,2,3,4,5';
    my @all_params = split( /,/, $params );
    
    foreach my $entry (@all_param) {
       $manager->start and next;
       #your code to run in parallel here;
       print $entry;
       $manager->finish;
    }

    Können Sie nur Rollen Sie Ihre eigenen mit fork aber du bist wahrscheinlich zu stolpern, das zu tun. So Parallel::ForkManager ist das Werkzeug für den job.

    Thread:

    #!/usr/bin/env perl
    
    use strict;
    use warnings;
    
    use threads;
    use Thread::Queue
    
      my $work_q = Thread::Queue->new;
    
    sub worker {
       while ( my $item = $work_q->dequeue ) {
          print $item, "\n";
       }
    }
    
    my $params = '1,2,3,4,5';
    my @all_params = split( /,/, $params );
    $work_q->enqueue(@all_params);
    $work_q->end;
    
    threads->create( \&worker ) for 1 .. 2;    #2 in parallel
    foreach my $thr ( threads->list ) {
       $thr->join;
    }

    Dies ist mehr geeignet wenn Sie müssen mehr tun, IPC – threading ist (IMO) in der Regel besser für die. Jedoch, Sie sollte nicht behandeln threads, wie leicht (wie die Gabel), weil trotz was Sie denken vielleicht, aus anderen Sprachen – perl-threading nicht wie das funktioniert.

    Mit IO::Select und mehrere open Aufrufe parallelise:

    #!/usr/bin/env perl
    
    use strict;
    use warnings;
    
    use IO::Select; 
    
    my $params = '1,2,3,4,5';
    my @all_params = split( /,/, $params );
    
    foreach my $param ( @all_params ) { 
       open ( my $io, '-|', "program_name $param" ); 
       $select -> add ( $io ); 
    }
    
    while ( my $fh = $select -> can_read ) { 
       my $line = <$fh>;
       print $line; 
    }      

    Können Sie ähnlich über IPC::Run2 öffnen von Datei-Deskriptoren für STDIN und STDERR.

    Sollte Ich?

    Parallel-code ist nicht eine Magische Kugel. Was es tut, ist, reduzieren die ‚Blöcke‘ und können Sie Ressourcen verbrauchen. Wenn Ihr begrenzende Ressource ist die CPU, und Sie haben 10 CPUs, dann mit 10 parallel geht um Geschwindigkeit, die Sie bis.

    … aber wenn Ihr begrenzende Ressource ist IO – Netzwerk oder Bandbreite – es ist oft nicht helfen, weil der Streit eigentlich macht das problem noch schlimmer. Disk-Controller insbesondere bereits parallelise, prefetch und cache Recht effizient, so dass Sie Ihre Gewinne aus schlagen Sie parallel sind oft sehr marginal.

    • Vielen Dank @Sobrique für eine ausführliche Erklärung, es hat mir sehr geholfen beim Verständnis der Interna. Für jetzt bin ich mit der ForkManager Methode für parallele builds und Ihre mir erwarteten Ergebnisse. Nur für Neugier, ist es auch möglich zu implementieren, verschachtelte Gabeln? Ich möchte dies tun, um parallelise das baut nur noch mehr..
    • Ja. Sie können die Gabel und die Gabel wieder – jedes mal, wenn Sie ‚Gabel‘ Sie teilen Ihren Prozess in zwei identische Kopien mit genau dem gleichen Zustand, abgesehen von den return-code des fork. Dies zu tun ist jedoch ein ziemlich guter Weg zu gehen, exponential-und „fork-Bombe“, wenn Sie nicht WIRKLICH vorsichtig sind. Also besser stick mit Parallel::ForkManager im Allgemeinen.
    • Danke @Sobrique !
  2. 4

    Es gibt keine wirkliche Notwendigkeit, einen code schreiben (Perl oder andere), der zur Ausführung Ihres Skripts parallel können Sie nur verwenden, GNU Parallel und kontrollieren, wie viele laufen auf Zeit, wie viele unterschiedliche Server sind die scripts laufen über und wo die Ergebnisse gehen, und einfach über jeden anderen Aspekt.

    So, wenn Sie eine Datei namens params.txt enthält:

    param1 param2
    param3 param4

    können Sie nur tun dies in der Klemme:

    parallel -a params.txt perl {1} {2}

    Wenn Sie möchten, eine progress-bar, fügen Sie einfach --bar:

    parallel --bar ...

    Wenn Sie ausführen möchten genau 8 gleichzeitig:

    parallel -j 8 ...

    Wenn Sie möchten, um zu sehen, was es tun würde, ohne tatsächlich etwas zu tun:

    parallel --dry-run ...
    • Dank Mark, ja, wir können es so machen. Ich verwende in der Regel diese Art und Weise während der Ausführung von Skripts, die direkt von der bash-Eingabeaufforderung. Dieser Anwendungsfall, die ich umsetzen will, ist in Jenkins2.x, wo ich ausführen möchten einige build-Skripte parallel. Ich bin leider Probleme in mit dem eingebauten jenkins „parallel“ – Befehl für diesen Zweck.

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.