Zoeken…


Invoering

Taken in GNU Linux kunnen worden parallel gemaakt met GNU parallel. Een taak kan een enkele opdracht zijn of een klein script dat moet worden uitgevoerd voor elk van de regels in de invoer. De typische invoer is een lijst met bestanden, een lijst met hosts, een lijst met gebruikers, een lijst met URL's of een lijst met tabellen. Een taak kan ook een opdracht zijn die van een pijp wordt gelezen.

Syntaxis

  1. parallel [opties] [opdracht [argumenten]] <lijst_van_argumenten>

parameters

Optie Beschrijving
-jn Voer n taken parallel uit
-k Behoud dezelfde volgorde
-X Meerdere argumenten met context vervangen
--colsep regexp Gesplitste invoer op regexp voor positionele vervangingen
{} {.} {/} {/.} {#} Vervangende snaren
{3} {3.} {3/} {3/.} Positie vervangende snaren
-S sshlogin Example: [email protected]
--trc {}.bar Afkorting voor --transfer --return {} .bar --cleanup
--onall Voer de gegeven opdracht met argument uit op alle sshlogins
--nonall Voer de gegeven opdracht uit zonder argumenten voor alle sshlogins
--pipe Split stdin (standaardinvoer) in meerdere taken.
--recend str Record-eindscheider voor --pipe.
--recstart str Record startscheider voor --pipe.

Parallelle taken herhalen op lijst met bestanden

Veel repetitieve taken kunnen efficiënter worden uitgevoerd als u meer van uw computerbronnen (CPU's en RAM) gebruikt. Hieronder ziet u een voorbeeld van het parallel uitvoeren van meerdere taken.

Stel dat u een < list of files > , bijvoorbeeld uitvoer van ls . Laat deze bestanden ook bz2-gecomprimeerd zijn en de volgende volgorde van taken moet erop worden uitgevoerd.

  1. Decomprimeer de bz2-bestanden met behulp van bzcat naar stdout
  2. Grep (bijv. Filter) lijnen met specifiek trefwoord (en) met behulp van grep <some key word>
  3. Spuit de uitvoer die moet worden samengevoegd in één enkel gzip-bestand met behulp van gzip

Dit uitvoeren met een while-lus kan er zo uitzien

filenames="file_list.txt"
while read -r line
do
name="$line"
     ## grab lines with puppies in them
     bzcat $line | grep puppies | gzip >> output.gz
done < "$filenames"

Met GNU Parallel kunnen we 3 parallelle taken tegelijk uitvoeren door simpelweg te doen

parallel -j 3 "bzcat {} | grep puppies" ::: $( cat filelist.txt ) | gzip > output.gz

Deze opdracht is eenvoudig, beknopt en efficiënter wanneer het aantal bestanden en de bestandsgrootte groot is. De taken worden parallel gestart, optie -j 3 lanceert 3 parallelle taken en invoer voor de parallelle taken wordt overgenomen door ::: . De uitvoer wordt uiteindelijk gzip > output.gz naar gzip > output.gz

STDIN parallel maken

Laten we ons nu eens voorstellen dat we 1 groot bestand (bijv. 30 GB) hebben dat regel voor regel moet worden geconverteerd. Stel dat we een script hebben, convert.sh , dat deze <task> . We kunnen de inhoud van dit bestand naar stdin doorgeven voor parallel opnemen en verwerken in brokken zoals

<stdin> | parallel --pipe --block <block size> -k <task> > output.txt

waarbij <stdin> afkomstig kan zijn van iets zoals cat <file> .

Als een reproduceerbaar voorbeeld zal onze taak nl -n rz . Neem een willekeurig bestand, het mijne is data.bz2 en geef het door aan <stdin>

bzcat data.bz2 | nl | parallel --pipe --block 10M -k nl -n rz | gzip > ouptput.gz

Het bovenstaande voorbeeld neemt <stdin> uit bzcat data.bz2 | nl , waar ik nl als een proof of concept heb opgenomen dat de uiteindelijke output output.gz wordt opgeslagen in de volgorde waarin deze werd ontvangen. Vervolgens verdeelt parallel de <stdin> in brokken van grootte 10 MB, en voor elke brok passeert het deze door nl -n rz waar het gewoon een terechte getallen toevoegt (zie nl --help voor meer informatie). De opties --pipe vertelt parallel om <stdin> in meerdere taken te splitsen en -- block geeft de grootte van de blokken aan. De optie -k geeft aan dat bestellen moet worden gehandhaafd.

Je uiteindelijke output zou er ongeveer zo uit moeten zien

000001       1  <data>
000002       2  <data>
000003       3  <data>
000004       4  <data>
000005       5  <data>
 ... 
000587  552409  <data>
000588  552410  <data>
000589  552411  <data>
000590  552412  <data>
000591  552413  <data>

Mijn oorspronkelijke bestand had 552.413 regels. De eerste kolom vertegenwoordigt de parallelle taken en de tweede kolom geeft de oorspronkelijke regelnummering weer die in delen aan parallel is doorgegeven. U moet opmerken dat de volgorde in de tweede kolom (en de rest van het bestand) wordt gehandhaafd.



Modified text is an extract of the original Stack Overflow Documentation
Licentie onder CC BY-SA 3.0
Niet aangesloten bij Stack Overflow