Ricerca…


introduzione

I lavori in GNU Linux possono essere parallelizzati usando GNU parallel. Un lavoro può essere un singolo comando o un piccolo script che deve essere eseguito per ciascuna delle righe nell'input. L'input tipico è un elenco di file, un elenco di host, un elenco di utenti, un elenco di URL o un elenco di tabelle. Un lavoro può anche essere un comando che legge da una pipe.

Sintassi

  1. parallel [opzioni] [comando [argomenti]] <lista_delle_grumenti>

Parametri

Opzione Descrizione
-jn Esegui n lavori in parallelo
-k Mantieni lo stesso ordine
-X Argomenti multipli con il contesto sostituito
--colsep regexp Dividi l'input su regexp per le sostituzioni posizionali
{} {.} {/} {/.} {#} Corde di ricambio
{3} {3.} {3/} {3/.} Stringhe di sostituzione posizionali
-S sshlogin Example: [email protected]
--trc {}.bar Abbreviazione di --transfer --return {} .bar --cleanup
--onall Esegui il comando dato con argomento su tutti gli sshlogins
--nonall Esegui il comando dato senza argomenti su tutti gli sshlogins
--pipe Split stdin (input standard) per più lavori.
--recend str Registrare il separatore finale per --pipe.
--recstart str Registrare il separatore iniziale per --pipe.

Parallelizza le attività ripetitive sull'elenco di file

Molti lavori ripetitivi possono essere eseguiti in modo più efficiente se si utilizzano più risorse del computer (ad esempio CPU e RAM). Di seguito è riportato un esempio di esecuzione di più lavori in parallelo.

Supponiamo di avere un < list of files > , per esempio l'output di ls . Inoltre, lascia che questi file siano compressi in bz2 e il seguente ordine di attività deve essere eseguito su di essi.

  1. Decomprimi i file bz2 usando bzcat stdout
  2. Grep (es. Filtro) linee con parole chiave specifiche usando grep <some key word>
  3. Pipe l'output da concatenare in un singolo file gzip usando gzip

L'esecuzione di questo con un ciclo while potrebbe essere simile a questa

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"

Usando GNU Parallel, possiamo eseguire 3 processi paralleli contemporaneamente semplicemente facendo

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

Questo comando è semplice, conciso e più efficiente quando il numero di file e le dimensioni del file sono grandi. I lavori vengono avviati in parallel , l'opzione -j 3 avvia 3 processi paralleli e l'input per i lavori paralleli viene eseguito da ::: . L'output viene infine inviato a gzip > output.gz

Parallelizzare STDIN

Ora, immaginiamo di avere 1 file di grandi dimensioni (ad es. 30 GB) che deve essere convertito, riga per riga. Diciamo che abbiamo uno script, convert.sh , che fa questo <task> . Siamo in grado di reindirizzare il contenuto di questo file a stdin per il parallelo da includere e lavorare con chunk come

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

dove <stdin> può provenire da qualcosa come cat <file> .

Come esempio riproducibile, il nostro compito sarà nl -n rz . Prendi qualsiasi file, il mio sarà data.bz2 e data.bz2 a <stdin>

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

L'esempio precedente prende <stdin> da bzcat data.bz2 | nl , dove ho incluso nl come prova del concetto che l'output finale output.gz verrà salvato nell'ordine in cui è stato ricevuto. Quindi, parallel divide lo <stdin> in blocchi di dimensione 10 MB, e per ogni blocco lo passa attraverso nl -n rz dove aggiunge semplicemente numeri giustificati (vedi nl --help per ulteriori dettagli). Le opzioni --pipe dice in parallel per dividere <stdin> in più lavori e -- block specifica la dimensione dei blocchi. L'opzione -k specifica che l'ordine deve essere mantenuto.

Il tuo risultato finale dovrebbe essere simile a qualcosa

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>

Il mio file originale aveva 552.413 linee. La prima colonna rappresenta i lavori paralleli e la seconda colonna rappresenta la numerazione delle righe originale passata al parallel in blocchi. Si dovrebbe notare che l'ordine nella seconda colonna (e resto del file) viene mantenuto.



Modified text is an extract of the original Stack Overflow Documentation
Autorizzato sotto CC BY-SA 3.0
Non affiliato con Stack Overflow