Parallellitet med xargs -P og bakgrunnsjobber
Kjør uavhengige oppgaver samtidig ved hjelp av parallellmodus i xargs og administrerte puljer med bakgrunnsjobber.
Parallellitet med xargs -P og bakgrunnsjobber er en gratis leksjon i DevOps-bootcamp på CoddyKit. Dette er leksjon 2 av 4. Du kan lese valgfritt 3 leksjoner fra denne læringsstien gratis i sin helhet – deretter låser CoddyKit PRO opp alle leksjoner, samt praktisk øving med en innebygd kodeeditor og en AI-veileder som er tilgjengelig døgnet rundt. Den er en del av læringsløpet i DevOps-bootcamp, og fremdriften din synkroniseres mellom nettet og CoddyKit-appen. Kurset i DevOps-bootcamp inneholder totalt 4 leksjoner.
Hvorfor sekvensiell kjøring er treg
Når De kjører kommandoer etter hverandre i et shell-skript, lar De CPU-kjerner stå ubrukt. Tenk på å endre størrelsen på 500 bilder: hvert kall til convert bruker én kjerne, mens de sju andre står ubrukt.
Parallellitet løser dette ved å sende ut flere oppgaver samtidig. To hovedverktøy i Bash gjør dette enkelt:
- xargs -P — fordeler en liste med inndata på N parallelle arbeiderprosesser
- Bakgrunnsjobber (&) + wait — oppretter prosesser manuelt og samler dem inn
Denne leksjonen dekker begge fremgangsmåtene, slik at De kan velge riktig verktøy for hver situasjon.
Oppfriskning av grunnleggende xargs
Før De legger til parallellitet, bør De huske hvordan xargs fungerer. Det leser elementer fra stdin og sender dem som argumenter til en kommando.
Flagget -I {} lar Dem plassere inndataelementet hvor som helst i kommandostrengen, ikke bare på slutten.
Eksempelet nedenfor konverterer alle .txt-filer til store bokstaver ved hjelp av tr. Hver fil behandles én om gangen (sekvensiell referanse).
#!/usr/bin/env bash
# Create sample files
mkdir -p /tmp/xargs_demo
for i in 1 2 3; do
echo "hello world $i" > /tmp/xargs_demo/file$i.txt
done
# Process files one at a time (sequential)
find /tmp/xargs_demo -name '*.txt' | xargs -I {} sh -c 'tr a-z A-Z < "$1"' _ {}
# Cleanup
rm -rf /tmp/xargs_demoIntroduksjon til xargs -P
Legg til flagget -P N i xargs for å kjøre opptil N prosesser parallelt. xargs administrerer arbeiderpoolen automatisk — når en plass blir ledig, starter neste element umiddelbart.
-P 0— opprett like mange prosesser som det finnes inndataelementer (brukes med forsiktighet for store lister)-P 4— hold maksimalt 4 arbeidere kjørende til enhver tid-n 1— send nøyaktig ett inndataelement per prosess som startes (et vanlig tilleggsflagg)
Sammen er -n 1 -P 4 det vanligste mønsteret: ett element per arbeider, fire arbeidere samtidig.
#!/usr/bin/env bash
# Simulate 8 tasks, each taking ~1 second
# Sequential would take ~8s; parallel with -P 4 takes ~2s
process_item() {
local item="$1"
sleep 1
echo "Done: $item"
}
export -f process_item
time printf '%s\n' task{1..8} | xargs -n 1 -P 4 bash -c 'process_item "$@"' _Parallell filbehandling
Et praktisk bruksområde er å komprimere mange loggfiler samtidig. Uten -P blokkerer hvert kall til gzip det neste. Med -P 8 kjører opptil åtte komprimeringer samtidig, slik at alle CPU-kjernene utnyttes.
Legg merke til at -n 1 sikrer at hver parallelle arbeider mottar nøyaktig ett filnavn — noe som er avgjørende når filnavn kan inneholde mellomrom (kombiner med -d '\n' eller -print0 / -0 for sikkerhets skyld).
#!/usr/bin/env bash
# Create dummy log files
mkdir -p /tmp/logs_demo
for i in $(seq 1 12); do
dd if=/dev/urandom bs=1K count=64 2>/dev/null > /tmp/logs_demo/app_$i.log
done
echo "Files before: $(ls /tmp/logs_demo | wc -l)"
# Compress all .log files in parallel (up to 8 workers)
find /tmp/logs_demo -name '*.log' -print0 \
| xargs -0 -n 1 -P 8 gzip --fast
echo "Files after : $(ls /tmp/logs_demo | wc -l)"
rm -rf /tmp/logs_demoVelge riktig -P-verdi
Hvis -P settes for lavt, sløses det med kjerner; hvis det settes for høyt, oppstår det ressurskonkurranse. Et godt utgangspunkt er antallet logiske CPU-kjerner:
- CPU-bundne oppgaver (komprimering, koding):
-P $(nproc) - I/O-bundne oppgaver (nettverkskall, diskkjøringer):
-P $(($(nproc) * 4))eller høyere, fordi arbeiderne bruker mesteparten av tiden på å vente - Minnebegrensede oppgaver: beregn
available_RAM / task_RAM_usageog sett grensen der
nproc returnerer antallet tilgjengelige prosesseringsenheter, og er dermed et portabelt alternativ til hardkodede tall.
#!/usr/bin/env bash
CORES=$(nproc)
IO_WORKERS=$(( CORES * 4 ))
echo "CPU cores : $CORES"
echo "CPU-bound -P: $CORES"
echo "I/O-bound -P: $IO_WORKERS"
# Example: parallel curl downloads (I/O-bound)
# printf '%s\n' url1 url2 ... | xargs -n 1 -P "$IO_WORKERS" curl -sSOBakgrunnsjobber med &
Noen ganger trenger De mer kontroll enn xargs tilbyr — feilhåndtering per jobb, dynamiske lister eller komplekse argumentstrukturer. Bruk skallprogrammenes innebygde bakgrunnsoperator & til å opprette jobber manuelt.
Når & legges til en kommando, får skriptet kontrollen tilbake umiddelbart. Underprosessen kjører i bakgrunnen mens foreldreprosessen fortsetter. Kall wait til slutt for å blokkere til alle underprosessene er ferdige.
#!/usr/bin/env bash
process() {
local id="$1"
sleep $(( RANDOM % 3 + 1 ))
echo "Job $id finished at $(date +%T)"
}
echo "Launching 5 background jobs..."
for id in $(seq 1 5); do
process "$id" &
done
wait # Block until every background job completes
echo "All jobs done."Begrense samtidighet med en jobbpool
Hvis alle jobbene opprettes samtidig med &, kan minnet bli brukt opp når listen er stor. En jobbpool holder maksimalt N jobber kjørende til enhver tid:
- Etter at hver jobb er opprettet, kontrollerer De hvor mange bakgrunnsjobber som er aktive med
jobs -r | wc -l - Når antallet når grensen, kaller De
wait -n(Bash 4.3+) for å vente på at én valgfri jobb skal bli ferdig før neste opprettes
Dette mønsteret etterligner det xargs -P gjør internt, men gir Dem full fleksibilitet i skriptet rundt hver jobb.
#!/usr/bin/env bash
MAX_JOBS=3
process() {
local id="$1"
sleep $(( RANDOM % 3 + 1 ))
echo "Task $id done"
}
for id in $(seq 1 10); do
# Throttle: wait for a slot if pool is full
while (( $(jobs -r | wc -l) >= MAX_JOBS )); do
wait -n 2>/dev/null || true
done
process "$id" &
done
wait
echo "All 10 tasks complete."Fange opp avslutningskoder fra parallelle jobber
En viktig utfordring med bakgrunnsjobber er at foreldreprosessen ikke automatisk får vite det hvis en underprosess mislykkes. De må fange opp PID-en til hver underprosess og kontrollere avslutningsstatusen med wait <pid>.
Mønsteret nedenfor lagrer alle PID-er i en array og går deretter gjennom arrayen med kall til wait "$pid", som returnerer avslutningskoden til den aktuelle underprosessen.
#!/usr/bin/env bash
set -euo pipefail
task() {
local id="$1"
sleep 1
if (( id == 3 )); then
echo "Task $id: FAILED" >&2
return 1
fi
echo "Task $id: ok"
}
pids=()
for id in $(seq 1 5); do
task "$id" &
pids+=("$!")
done
failed=0
for pid in "${pids[@]}"; do
if ! wait "$pid"; then
echo "PID $pid exited with error" >&2
(( failed++ ))
fi
done
(( failed == 0 )) && echo "All OK" || { echo "$failed job(s) failed"; exit 1; }Parallelle nedlastinger med xargs -P
Nettverks-I/O er et typisk tilfelle for høy parallellitet — hver arbeider bruker mesteparten av tiden på å vente på byte. Eksempelet nedenfor henter flere URL-er samtidig og lagrer hver av dem i en fil med et unikt navn.
Viktige flagg:
-P 8— åtte samtidige curl-prosesser-n 1— én URL per curl-kall--create-dirs -o— curl lagrer i et avledet filnavn
#!/usr/bin/env bash
# Download several small public files in parallel
URLs=(
"https://httpbin.org/bytes/1024"
"https://httpbin.org/bytes/2048"
"https://httpbin.org/bytes/512"
"https://httpbin.org/bytes/4096"
)
mkdir -p /tmp/parallel_dl
printf '%s\n' "${URLs[@]}" | xargs -n 1 -P 4 bash -c '
url="$1"
out="/tmp/parallel_dl/$(echo "$url" | md5sum | cut -c1-8).bin"
curl -sSf "$url" -o "$out" && echo "Saved $out"
' _
ls -lh /tmp/parallel_dl/
rm -rf /tmp/parallel_dlKombinere find, xargs -P og skallfunksjoner
For å bruke en skallfunksjon over flere linjer med xargs må De eksportere den med export -f function_name og deretter starte den via bash -c 'function_name "$@"' _ inne i xargs.
Dette mønsteret gir full skriptfunksjonalitet i hver parallelle arbeider: logging, feilhåndtering og betinget logikk — alt per element.
#!/usr/bin/env bash
mkdir -p /tmp/proc_demo
for i in $(seq 1 8); do echo "data $i" > /tmp/proc_demo/item_$i.txt; done
process_file() {
local f="$1"
local base
base=$(basename "$f" .txt)
# Simulate work: count words and append a timestamp
local wc
wc=$(wc -w < "$f")
echo "[$base] words=$wc processed=$(date +%T)" >> "/tmp/proc_demo/${base}.result"
}
export -f process_file
find /tmp/proc_demo -name '*.txt' -print0 \
| xargs -0 -n 1 -P "$(nproc)" bash -c 'process_file "$@"' _
grep '' /tmp/proc_demo/*.result
rm -rf /tmp/proc_demoMåle hastighetsøkning med time
Mål alltid før De hevder at noe er blitt bedre. Omslutt den parallelle kommandoen med time og sammenlign med den sekvensielle referansen. Den faktiske hastighetsøkningen avhenger av:
- Uavhengighet mellom oppgavene — oppgavene må ikke dele skrivbar tilstand uten låser
- Overhead — kostnaden ved å opprette prosesser (omtrent 5–20 ms per prosess) har betydning for små oppgaver
- Ressurskonkurranse — disk-I/O kan nå kapasitetsgrensen før CPU-en gjør det
Et enkelt referansemønster vises nedenfor — kjør først sekvensielt, deretter parallelt, og sammenlign real-tidene for faktisk medgått tid.
#!/usr/bin/env bash
work() { sleep 0.2; } # simulate a 200ms task
export -f work
ITEMS=$(seq 1 16)
echo "=== Sequential ==="
time printf '%s\n' $ITEMS | xargs -n 1 bash -c 'work' _
echo
echo "=== Parallel ($(nproc) workers) ==="
time printf '%s\n' $ITEMS | xargs -n 1 -P "$(nproc)" bash -c 'work' _Kunnskapssjekk: Virkemåten til xargs -P
Test forståelsen Deres av parallell kjøring med xargs -P.
Oppsummering av leksjonen
De har nå to pålitelige teknikker for parallell kjøring i Bash:
- xargs -n 1 -P N — den enkleste fremgangsmåten; xargs administrerer arbeiderpoolen automatisk. Best når inndataene er en vanlig liste og hvert element tilsvarer én kommando.
- Bakgrunnsjobber (&) + wait — full kontroll i skriptet; nødvendig når De trenger PID-er per jobb, dynamiske inndata eller detaljert håndtering av avslutningskoder. Bruk
wait -nmed en teller for å begrense samtidigheten.
Viktige regler å ta med videre:
- Eksporter skallfunksjoner med
export -ffør De sender dem gjennomxargs - Bruk
-print0/-0for å håndtere filnavn med mellomrom på en sikker måte - Fang opp PID-er i en array og kall
wait "$pid"individuelt for å oppdage feil - Gjør referansemålinger med
time— parallellitet gir bare gevinst når oppgavenes overhead er større enn kostnaden ved å opprette prosesser - Bruk
-P $(nproc)for CPU-bundne og en høyere faktor for I/O-bundne arbeidsbelastninger
Lær deg DevOps-bootcamp med en AI-veileder – gratis
Skriv og kjør ekte kode i nettleseren, få umiddelbar hjelp fra en AI-veileder som er tilgjengelig døgnet rundt, og fortsett der du slapp – på nettet eller i appen.
- Kurs
- 142
- Leksjoner
- 568
Ofte stilte spørsmål
Er leksjonen «Parallellitet med xargs -P og bakgrunnsjobber» gratis?
Ja – du kan lese valgfritt 3 av leksjonene i læringsstien DevOps-bootcamp, inkludert «Parallellitet med xargs -P og bakgrunnsjobber», gratis i sin helhet her på nettet. Deretter låser CoddyKit PRO opp alle leksjoner, samt interaktiv øving med en innebygd kodeeditor og en AI-veileder som er tilgjengelig døgnet rundt. Kurset i DevOps-bootcamp inneholder totalt 4 leksjoner.
Hva lærer jeg i «Parallellitet med xargs -P og bakgrunnsjobber»?
Kjør uavhengige oppgaver samtidig ved hjelp av parallellmodus i xargs og administrerte puljer med bakgrunnsjobber. Du øver på DevOps-bootcamp med praktisk kode som du kjører direkte i nettleseren, mens en AI-veileder som er tilgjengelig døgnet rundt, svarer på spørsmålene dine mens du jobber deg gjennom leksjonen.
Trenger jeg erfaring for å begynne med DevOps-bootcamp?
Ingen tidligere erfaring er nødvendig. DevOps-bootcamp på CoddyKit er lagt opp for både nybegynnere og viderekomne, så De kan begynne her eller helt fra start og lære i Deres eget tempo. Dette er leksjon 2 av 4.
Hvor lang tid tar leksjonen «Parallellitet med xargs -P og bakgrunnsjobber»?
De fleste CoddyKit-leksjoner tar omtrent 5–10 minutter. Hver leksjon er kort og interaktiv, slik at De gjør jevne fremskritt og kan fortsette akkurat der De slapp – både på nettet og i appen.
Kan jeg skrive og kjøre kode i denne DevOps-bootcamp-leksjonen?
Ja. Alle DevOps-bootcamp-leksjoner har en innebygd kodeeditor, slik at De kan skrive og kjøre ekte kode direkte i nettleseren og få umiddelbar tilbakemelding fra AI – uten lokal konfigurering.
Alle leksjonene i dette kurset
- Profilering av skript og unngåelse av unødvendige subshell-er
- Parallellitet med xargs -P og bakgrunnsjobber
- Orkestrering av arbeidsmengder med GNU parallel
- Strømmende pipelines og navngitte pipes for høy gjennomstrømning