Orkestrera arbetsbelastningar med GNU parallel
Fördela stora indatamängder över kärnor med GNU parallel, jobbplatser och ordning på resultaten.
Orkestrera arbetsbelastningar med GNU parallel är en gratis lektion i Bemästra Linux-kommandoraden och Bash-skriptning på CoddyKit. Detta är lektion 3 av 4. Ni kan läsa hela lektionen gratis nedan och sedan öva praktiskt i webbläsaren med en inbyggd kodredigerare och en AI-handledare som är tillgänglig dygnet runt. Den ingår i lärvägen för Bemästra Linux-kommandoraden och Bash-skriptning, och Era framsteg synkroniseras mellan webben och CoddyKit-appen. Kursen i Bemästra Linux-kommandoraden och Bash-skriptning innehåller totalt 4 lektioner.
Vad är GNU parallel och varför ska det användas?
GNU parallel är ett shell-verktyg som låter er köra jobb parallellt på en eller flera maskiner. I stället för att behandla en stor lista med objekt ett i taget i en for-loop fördelar parallel arbetet över alla tillgängliga CPU-kärnor samtidigt.
- Hastighet: En uppgift som tar 8 minuter sekventiellt kan bli klar på cirka 1 minut på en maskin med 8 kärnor.
- Enkelhet: Verktyget accepterar indata från stdin, filer eller argumentlistor – ingen manuell processhantering krävs.
- Säkerhet: Utdata från olika jobb hålls åtskilda; resultaten blandas aldrig ihop.
Installera det med sudo apt install parallel (Debian/Ubuntu) eller brew install parallel (macOS). Verifiera installationen med parallel --version.
Ert första parallel-kommando
Den enklaste formen av parallel läser objekt från stdin och kör ett kommando för varje objekt. Platshållaren {} representerar det aktuella indat objektet.
Exemplet nedan komprimerar fem loggfiler samtidigt med gzip. Utan parallel skulle varje fil komprimeras efter den föregående. Med verktyget komprimeras upp till N filer (där N = antalet CPU-kärnor) samtidigt.
#!/usr/bin/env bash
# Create sample files first
for i in 1 2 3 4 5; do
dd if=/dev/urandom bs=1M count=2 of="log_${i}.txt" 2>/dev/null
done
# Compress all of them in parallel
ls log_*.txt | parallel gzip {}
echo "Done. Compressed files:"
ls log_*.txt.gzStyr jobbplatser med -j
Som standard kör parallel ett jobb per CPU-kärna. Ni kan ändra detta med flaggan -j (eller --jobs).
-j 4– kör exakt 4 jobb samtidigt-j 0– kör lika många jobb som det finns indata (använd med försiktighet!)-j 200%– kör dubbelt så många jobb som det finns CPU-kärnor (användbart för I/O-bundet arbete)-j 50%– använd endast hälften av de tillgängliga kärnorna
För CPU-bundna uppgifter är -j $(nproc) ofta optimalt. För nätverks- eller disk-I/O-uppgifter kan ni utan problem överskrida antalet kärnor, eftersom jobben tillbringar större delen av tiden med att vänta.
#!/usr/bin/env bash
# Show how many cores are available
echo "CPU cores: $(nproc)"
# Run 8 sleep jobs but limit to 3 at a time
# -j 3 means at most 3 jobs run simultaneously
seq 1 8 | parallel -j 3 'echo "Starting job {}"; sleep 1; echo "Done job {}"'
echo "All jobs finished."Läs indata från filer och argument
parallel är flexibelt när det gäller varifrån indatalistan läses. Ni är inte begränsade till att skicka indata från stdin via en pipe.
- Från en fil:
parallel -a urls.txt wget {} - Argumentlista direkt i kommandot:
parallel echo ::: apple banana cherry - Flera argumentkällor (kartesisk produkt):
parallel echo {1}-{2} ::: a b c ::: 1 2– producerar a-1, a-2, b-1, b-2, c-1, c-2 - Uttryckligen från stdin:
cat list.txt | parallel -j4 process {}
Avgränsaren ::: talar om för parallel att använda de följande värdena som en argumentkälla i stället för att läsa från stdin.
#!/usr/bin/env bash
# Inline list with :::
parallel echo 'Hello from {}' ::: Alice Bob Carol Dave
echo '---'
# Cartesian product: combine two lists
# Generates: dev-v1, dev-v2, prod-v1, prod-v2
parallel echo 'Deploy {1} to env {2}' ::: v1 v2 ::: dev prodPlatshållare: manipulera indatatoken
parallel tillhandahåller flera platshållarsubstitutioner som automatiskt låter er extrahera delar av indatasträngen – mycket användbart när indata är filsökvägar.
{}– hela indatat{.}– indata utan filändelse (report.csv → report){/}– endast basnamnet (katalogsökvägen tas bort){//}– endast katalogsökvägen{/.}– basnamnet utan filändelse
Detta eliminerar behovet av anrop till basename / dirname i jobbkommandot och gör pipelines renare och snabbare.
#!/usr/bin/env bash
# Demonstrate placeholder substitutions
parallel --dry-run 'convert {} -resize 800x600 {.}_thumb.jpg' \
::: /photos/vacation/beach.png /photos/work/team.png
# {.} strips extension: /photos/vacation/beach
# Result command shown (--dry-run does NOT execute):
# convert /photos/vacation/beach.png -resize 800x600 /photos/vacation/beach_thumb.jpg
# convert /photos/work/team.png -resize 800x600 /photos/work/team_thumb.jpg
echo 'No files were changed (dry run)'Behåll utdataordningen med --keep-order
När jobb blir klara vid olika tidpunkter visas deras stdout-utdata i den ordning de slutförs. Det kan göra loggar svårlästa och efterföljande tolkning opålitlig.
Två flaggor styr utdataordningen:
--keep-order(-k) – skriver ut varje jobbs utdata i samma ordning som indatan, även om ett senare jobb blir klart först. Utdata buffras tills tidigare jobb är klara.--line-buffer– en kompromiss: skriver ut kompletta rader när de anländer utan att vänta tills jobbet är klart, men blandar aldrig ihop halvt skrivna rader.
Använd -k när den efterföljande mottagaren förväntar sig resultat i indatans ordning (till exempel när ni bygger en sorterad rapport). Utelämna den när ordningen saknar betydelse och ni vill se resultaten så snart som möjligt.
#!/usr/bin/env bash
# Without -k: output order is unpredictable
echo '--- Without --keep-order ---'
seq 5 1 1 | parallel 'sleep 0.$((RANDOM % 5)); echo "Result for {}"'
echo
# With -k: output always appears as 5, 4, 3, 2, 1
echo '--- With --keep-order (-k) ---'
seq 5 1 1 | parallel -k 'sleep 0.$((RANDOM % 5)); echo "Result for {}"'Gruppera utdata för att undvika sammanflätning
Även med ordnad utdata kan raderna från ett jobb sammanflätas med rader från ett annat jobb som körs samtidigt, om jobbet skriver ut flera rader. parallel löser detta automatiskt genom att buffra varje jobbs fullständiga stdout och stderr och sedan skriva ut dem som ett enda atomiskt block när jobbet är klart.
Detta beteende är aktiverat som standard. Ni kan inaktivera det med --ungroup om ni behöver utdata som strömmas i realtid (till exempel långkörande jobb med förloppsindikatorer), men då kan utdata återigen sammanflätas.
- Standard: utdata grupperas per jobb — säkert för parsning.
--ungroup: utdata strömmas i realtid — bra för interaktiv övervakning.--line-buffer: en kompromiss — rader delas aldrig upp, men jobb kan sammanflätas vid radgränser.
Skicka argument till skal-funktioner
Ibland består arbetet som ni vill parallellisera av mer än ett enda kommando — det är en skal-funktion med flera steg. Ni kan skicka en funktion till parallel genom att kombinera export -f med env_parallel, eller genom att anropa bash -c direkt.
Det säkraste portabla tillvägagångssättet för komplexa jobb är mönstret bash -c '...'. Platshållaren {} skickas som $1 när ni avslutar med _ {}.
#!/usr/bin/env bash
# Define a multi-step processing function
process_item() {
local item="$1"
echo "[START] $item"
# Simulate two steps
sleep 0.2
local result=$(echo "$item" | tr '[:lower:]' '[:upper:]')
echo "[END] $item -> $result"
}
export -f process_item
# Run the function in parallel for each input
echo 'alpha beta gamma delta epsilon' | tr ' ' '\n' \
| parallel -j 3 process_item {}Begränsa hastighet och försök igen med --delay och --retries
När ni anropar externa tjänster (API:er, fjärrservrar, databaser) parallellt behöver ni ofta begränsa anropsfrekvensen och hantera fel robust.
--delay N— väntar N sekunder mellan starterna av nya jobb (decimala värden som0.5är tillåtna). Förhindrar att en tjänst överbelastas.--retries N— om ett jobb avslutas med en status som inte är noll försökerparallelköra det igen upp till N gånger innan det ger upp. Varje nytt försök räknas som en ny jobbplats.--timeout N— avslutar ett jobb om det körs längre än N sekunder. Tillsammans med--retrieshanterar detta jobb som har hängt sig på ett smidigt sätt.
Exempel: ladda ned 50 URL:er med högst 4 samtidiga anslutningar, 0,5 sekunders fördröjning mellan starter och 3 nya försök vid fel.
#!/usr/bin/env bash
# Simulate downloading URLs with throttling and retries
# (using echo instead of curl so this is self-contained)
download_url() {
local url="$1"
# Randomly fail ~30% of the time to demo --retries
if (( RANDOM % 10 < 3 )); then
echo "FAIL: $url" >&2
return 1
fi
echo "OK: $url downloaded"
}
export -f download_url
printf 'https://example.com/file%d\n' $(seq 1 10) \
| parallel -j 4 --delay 0.2 --retries 3 download_url {}
echo 'All downloads attempted.'Fördela arbete mellan fjärrvärdar med --sshloginfile
parallel kan transparent fördela jobb till fjärrdatorer via SSH och fungerar därmed som ett lättviktigt verktyg för klusterberäkningar utan särskild klusterprogramvara.
--sshlogin user@host— kör jobb på en specifik fjärrvärd.--sshloginfile machines.txt— läser en lista över värdar från en fil (en per rad). Använd:som en särskild post om även den lokala datorn ska användas.--transfer— kopierar indatafilen till fjärrvärden före bearbetningen.--return {}— kopierar resultatfilen tillbaka när jobbet är klart.--cleanup— tar bort överförda filer från fjärrvärden efter hämtningen.
Fjärrvärden måste ha parallel installerat och SSH-autentisering med nycklar konfigurerad (utan lösenordsfrågor).
Rapportera förlopp och logga händelser
För långkörande arbetslaster är det viktigt att övervaka förloppet och kunna felsöka problem i efterhand.
--progress— skriver ut en sammanfattande rad i realtid som visar hur många jobb som körs, har slutförts och återstår.--eta— uppskattar tiden tills körningen är klar baserat på den genomsnittliga jobbtiden hittills.--joblog results.log— skriver en tabbseparerad loggfil med en rad per slutfört jobb, inklusive avslutskod, körtid och det körda kommandot. Ovärderligt för att granska fel.--resume --joblog results.log— hoppar över jobb som redan finns i loggfilen med avslutskod 0. Om en batchkörning avbryts kan ni återuppta den utan att göra om arbete som redan lyckats.
Kombinationen --joblog + --resume är en av de mest kraftfulla funktionerna i GNU parallel för robusta produktionspipeline:er.
#!/usr/bin/env bash
LOGFILE="/tmp/parallel_demo_$$.log"
# Run jobs and record results to a log
seq 1 12 | parallel \
--jobs 4 \
--progress \
--joblog "$LOGFILE" \
'sleep 0.1; echo "Processed item {}"'
echo
echo '=== Job Log (first 5 entries) ==='
head -6 "$LOGFILE"
# Show only failed jobs (exit value != 0)
echo '=== Failed jobs ==='
awk 'NR>1 && $7 != 0 { print $0 }' "$LOGFILE" || echo '(none)'
rm -f "$LOGFILE"Kunskapskontroll: flaggor för jobbplatser
Testa hur väl ni förstår hur parallel styr samtidigheten.
Lektionssammanfattning: orkestrera arbetslaster med GNU parallel
Ni har gått igenom de viktigaste verktygen för att fördela stora mängder indata över CPU-kärnor med GNU parallel. Detta är det viktigaste att ta med sig:
- Grundläggande användning: skicka en lista genom
parallel command {}—{}ersätts med varje indataobjekt. - Jobbplatser (
-j): styr samtidigheten exakt — använd antalet kärnor för CPU-bundet arbete och högre procenttal för I/O-bundet arbete. - Platshållare (
{.},{/},{//},{/.}) extraherar sökvägskomponenter smidigt utan extra kommandon. - Utdatahantering:
-kbevarar indatans ordning; standardgrupperingen förhindrar sammanflätade rader;--ungroupger strömning i realtid. - Robusthet:
--retries,--timeoutoch--delaygör parallella pipeline:er motståndskraftiga mot instabila jobb och hastighetsbegränsningar. - Spårbarhet:
--joblogregistrerar resultatet för varje jobb;--resumelåter er fortsätta där ni slutade efter ett avbrott. - Utskalning:
--sshloginfilefördelar jobb till fjärrdatorer via SSH utan någon extra klusterinfrastruktur.
När ni behärskar dessa alternativ blir parallel en produktionsklar orkestrerare för arbetslaster, direkt inbyggd i skalet.
Lär dig Bash med en AI-lärare – gratis
Skriv och kör riktig kod i webbläsaren, få omedelbar hjälp av en AI-lärare dygnet runt och fortsätt där du slutade – på webben eller i appen.
- Kurser
- 22
- Lektioner
- 88
Vanliga frågor
Är lektionen ”Orkestrera arbetsbelastningar med GNU parallel” gratis?
Ja – hela texten till ”Orkestrera arbetsbelastningar med GNU parallel” kan läsas gratis här på webben. Om Ni vill öva interaktivt med en inbyggd kodredigerare och en AI-handledare som är tillgänglig dygnet runt och låsa upp resten av kursen i Bemästra Linux-kommandoraden och Bash-skriptning, kan Ni uppgradera till CoddyKit PRO. Kursen i Bemästra Linux-kommandoraden och Bash-skriptning innehåller totalt 4 lektioner.
Vad lär jag mig i ”Orkestrera arbetsbelastningar med GNU parallel”?
Fördela stora indatamängder över kärnor med GNU parallel, jobbplatser och ordning på resultaten. Ni övar på Bemästra Linux-kommandoraden och Bash-skriptning med praktisk kod som körs direkt i webbläsaren, medan en AI-handledare som är tillgänglig dygnet runt svarar på Era frågor under lektionen.
Behöver jag någon erfarenhet för att börja lära mig Bemästra Linux-kommandoraden och Bash-skriptning?
Du behöver inga förkunskaper. Utbildningen i Bemästra Linux-kommandoraden och Bash-skriptning på CoddyKit är upplagd för allt från nybörjare till avancerade elever, så att du kan börja här eller från början och gå fram i din egen takt. Detta är lektion 3 av 4.
Hur lång tid tar lektionen ”Orkestrera arbetsbelastningar med GNU parallel”?
De flesta CoddyKit-lektioner tar cirka 5–10 minuter. Varje lektion är kort och interaktiv, så att du gör stadiga framsteg och kan fortsätta precis där du slutade – på webben eller i appen.
Kan jag skriva och köra kod i den här Bemästra Linux-kommandoraden och Bash-skriptning-lektionen?
Ja. Varje Bemästra Linux-kommandoraden och Bash-skriptning-lektion innehåller en inbyggd kodredigerare, så att du kan skriva och köra riktig kod direkt i webbläsaren och få omedelbar AI-feedback – utan lokal installation.
Alla lektioner i den här kursen
- Profilera skript och undvik onödiga subshells
- Parallellism med xargs -P och bakgrundsjobb
- Orkestrera arbetsbelastningar med GNU parallel
- Strömmande pipelines och namngivna pipes för genomströmning