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
- 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.
- Decomprimeer de bz2-bestanden met behulp van
bzcat
naar stdout - Grep (bijv. Filter) lijnen met specifiek trefwoord (en) met behulp van
grep <some key word>
- 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.