Rinnakkaisuus xargs -P:llä ja taustatöillä
Suorita toisistaan riippumattomia tehtäviä samanaikaisesti xargsin rinnakkaistilalla ja hallituilla taustatyöjoukoilla.
Rinnakkaisuus xargs -P:llä ja taustatöillä on ilmainen DevOps-bootcamp-oppitunti CoddyKitissä. Tämä on oppitunti 2/4. Voit lukea tästä oppimispolusta kokonaan mitkä tahansa 3 oppituntia ilmaiseksi — sen jälkeen CoddyKit PRO avaa kaikki oppitunnit sekä käytännön harjoittelun sisäänrakennetulla koodieditorilla ja ympäri vuorokauden toimivalla tekoälytuutorilla. Oppitunti kuuluu DevOps-bootcamp-oppimispolkuun, ja edistymisesi synkronoituu verkon ja CoddyKit-sovelluksen välillä. DevOps-bootcamp-kurssilla on yhteensä 4 oppituntia.
Miksi peräkkäinen suoritus on hidasta
Kun suoritatte komentoja peräkkäin shell-komentosarjassa, jätätte suorittimen ytimiä käyttämättä. Kuvitelkaa, että muutatte 500 kuvan kokoa: jokainen convert-kutsu käyttää yhtä ydintä, kun taas seitsemän muuta ovat käyttämättöminä.
Rinnakkaisuus ratkaisee tämän jakamalla useita tehtäviä suoritettavaksi samanaikaisesti. Bashissa on kaksi ensisijaista työkalua, jotka tekevät tästä helppoa:
- xargs -P — jakaa syöteluettelon N rinnakkaisen työntekijäprosessin kesken
- Taustatyöt (&) + wait — luo prosessit manuaalisesti ja kerää ne
Tässä oppitunnissa käsitellään molempia lähestymistapoja, jotta voitte valita kuhunkin tilanteeseen sopivan työkalun.
xargs-komennon perusteiden kertaus
Ennen rinnakkaisuuden lisäämistä palautetaan mieleen, miten xargs toimii. Se lukee kohteita vakiosyötteestä ja välittää ne komennolle argumenteiksi.
Lipun -I {} avulla syötekohdan voi sijoittaa mihin tahansa kohtaan komentomerkkijonossa, ei vain sen loppuun.
Alla oleva esimerkki muuntaa jokaisen .txt-tiedoston isokirjaimiseksi tr-komennolla. Kukin tiedosto käsitellään yksi kerrallaan (peräkkäisen suorituksen vertailukohta).
#!/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_demoxargs -P:n esittely
Lisätkää -P N-lippu xargs-komentoon, jotta enintään N prosessia suoritetaan rinnakkain. xargs hallinnoi työntekijäjoukkoa automaattisesti — kun yksi paikka vapautuu, seuraavan kohteen käsittely alkaa heti.
-P 0— luo yhtä monta prosessia kuin syötteitä on (käyttäkää varoen suurten luetteloiden kanssa)-P 4— pitää samanaikaisesti käynnissä enintään 4 työntekijää-n 1— välittää täsmälleen yhden syötekohteen kutakin käynnistettyä prosessia kohti (yleinen kumppanilippu)
Yhdessä -n 1 -P 4 muodostaa yleisimmän mallin: yksi kohde työntekijää kohti ja neljä työntekijää samanaikaisesti.
#!/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 "$@"' _Tiedostojen rinnakkainen käsittely
Käytännöllinen käyttötapaus on useiden lokitiedostojen pakkaaminen samanaikaisesti. Ilman -P-lippua jokainen gzip-kutsu estää seuraavan käynnistymisen. Lipulla -P 8 enintään kahdeksan pakkausta suoritetaan yhtä aikaa, jolloin kaikki suorittimen ytimet saadaan käyttöön.
Huomaattehan, että -n 1 varmistaa jokaiselle rinnakkaiselle työntekijälle täsmälleen yhden tiedostonimen — tämä on tärkeää, jos tiedostonimissä voi olla välilyöntejä (yhdistäkää tarvittaessa lippuun -d '\n' tai käyttäkää turvallisesti vaihtoehtoja -print0 / -0).
#!/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_demoSopivan -P-arvon valinta
Liian pieni -P-arvo jättää ytimiä käyttämättä, kun taas liian suuri arvo aiheuttaa thrashing-ilmiötä. Hyvä lähtökohta on loogisten suoritinytimien määrä:
- Suoritinrajoitteiset tehtävät (pakkaus, koodaus):
-P $(nproc) - Siirräntärajoitteiset tehtävät (verkkokutsut, levyltä lukeminen):
-P $(($(nproc) * 4))tai suurempi, koska työntekijät käyttävät suurimman osan ajasta odottamiseen - Muistirajoitteiset tehtävät: laskekaa
available_RAM / task_RAM_usageja rajoittakaa määrä siihen
nproc palauttaa käytettävissä olevien suoritinyksiköiden määrän, joten se on siirrettävämpi vaihtoehto kovakoodatuille luvuille.
#!/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 -sSOTaustatyöt merkillä &
Joskus tarvitsette enemmän hallintaa kuin xargs tarjoaa — työkohtaisen virheenkäsittelyn, dynaamiset luettelot tai monimutkaiset argumenttirakenteet. Käyttäkää shellin sisäänrakennettua taustaoperaattoria & työpaikkojen luomiseen manuaalisesti.
Kun lisäätte &-merkin mihin tahansa komentoon, komentosarja saa hallinnan heti takaisin. Lapsiprosessi suoritetaan taustalla, kun taas isäntä jatkaa toimintaansa. Kutsukaa lopuksi komentoa wait, jotta suoritus odottaa kaikkien lapsiprosessien valmistumista.
#!/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."Samanaikaisuuden rajoittaminen työjoukolla
Kaikkien työpaikkojen luominen kerralla merkillä & voi kuluttaa muistin loppuun, jos luettelo on suuri. Työjoukko pitää samanaikaisesti käynnissä enintään N työtä:
- Tarkistakaa jokaisen työn luonnin jälkeen, kuinka monta taustatyötä on parhaillaan aktiivisena komennolla
jobs -r | wc -l - Jos määrä saavuttaa rajan, kutsukaa komentoa
wait -n(Bash 4.3+), jotta minkä tahansa yhden työn valmistumista odotetaan ennen seuraavan luomista
Tämä malli jäljittelee sitä, mitä xargs -P tekee sisäisesti, mutta antaa täyden joustavuuden kunkin työn ympärillä toteutettavaan komentosarjaan.
#!/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."Rinnakkaisten töiden paluuarvojen talteenotto
Taustatöihin liittyy tärkeä huomio: jos lapsiprosessi epäonnistuu, isäntäkomentosarja ei saa siitä automaattisesti tietoa. Teidän on tallennettava kunkin lapsiprosessin PID ja tarkistettava sen poistumisstatus komennolla wait <pid>.
Alla oleva malli tallentaa jokaisen PID:n taulukkoon ja käy sitten taulukon läpi kutsuen komentoa wait "$pid", joka palauttaa kyseisen lapsiprosessin poistumiskoodin.
#!/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; }Rinnakkaiset lataukset xargs -P:llä
Verkon siirräntä on tyypillinen tapaus, jossa rinnakkaisuudesta on paljon hyötyä — kukin työntekijä käyttää suurimman osan ajasta tavujen odottamiseen. Alla oleva esimerkki noutaa useita URL-osoitteita samanaikaisesti ja tallentaa kunkin yksilöllisesti nimettyyn tiedostoon.
Käytetyt tärkeimmät liput:
-P 8— kahdeksan samanaikaista curl-prosessia-n 1— yksi URL-osoite kutakin curl-kutsua kohti--create-dirs -o— curl tallentaa tiedot johdetulla tiedostonimellä
#!/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_dlfind-, xargs -P- ja shell-funktioiden yhdistäminen
Jos haluatte käyttää monirivistä shell-funktiota komennon xargs kanssa, se on ensin vietävä komennolla export -f function_name ja kutsuttava sitten xargsin sisällä komennolla bash -c 'function_name "$@"' _.
Tämä malli tarjoaa täyden komentosarjojen ilmaisuvoiman kussakin rinnakkaisessa työntekijässä: lokituksen, virheenkäsittelyn ja ehdollisen logiikan — kaikki kohdekohtaisesti.
#!/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_demoNopeutuksen mittaaminen time-komennolla
Mitatkaa aina ennen kuin väitätte suorituskyvyn parantuneen. Suorittakaa rinnakkainen komento komennon time avulla ja verratkaa tulosta peräkkäisen suorituksen vertailukohtaan. Todellinen nopeutus riippuu seuraavista tekijöistä:
- Tehtävien riippumattomuus — tehtävät eivät saa jakaa kirjoitettavaa tilaa ilman lukkoja
- Yleiskustannukset — prosessin luonnin kustannuksella (noin 5–20 ms prosessia kohti) on merkitystä pienissä tehtävissä
- Resurssien kilpailu — levy-I/O voi saavuttaa kapasiteettinsa ennen suorittimen kuormittumista
Alla on yksinkertainen vertailumalli — suorittakaa komento ensin peräkkäin ja sitten rinnakkain ja verratkaa real-aikoja.
#!/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' _Tietotesti: xargs -P:n toiminta
Testatkaa ymmärrystänne rinnakkaisesta suorituksesta komennolla xargs -P.
Oppitunnin kertaus
Teillä on nyt kaksi luotettavaa tekniikkaa rinnakkaiseen suoritukseen Bashissa:
- xargs -n 1 -P N — yksinkertaisin lähestymistapa; xargs hallinnoi työntekijäjoukkoa automaattisesti. Sopii parhaiten, kun syöte on tavallinen luettelo ja kukin kohde vastaa yhtä komentoa.
- Taustatyöt (&) + wait — täysi hallinta komentosarjalla; välttämätön, kun tarvitsette työkohtaiset PID:t, dynaamisen syötteen tai tarkasti hallitun poistumiskoodien käsittelyn. Käyttäkää komentoa
wait -nyhdessä laskurin kanssa samanaikaisuuden rajoittamiseen.
Tärkeät säännöt jatkoa varten:
- Viekää shell-funktiot komennolla
export -fennen niiden välittämistäxargs-komennolle - Käyttäkää komentoja
-print0/-0, jotta välilyöntejä sisältävät tiedostonimet käsitellään turvallisesti - Tallentakaa PID:t taulukkoon ja kutsukaa komentoa
wait "$pid"erikseen kunkin kohdalla virheiden havaitsemiseksi - Vertailkaa suorituskykyä komennolla
time— rinnakkaisuus kannattaa vain, kun tehtävien yleiskustannukset ylittävät prosessien luonnin kustannukset - Asettakaa suorittimesta riippuville kuormille
-P $(nproc)ja siirräntäriippuville kuormille suurempi kerroin
Opi DevOps-bootcamp tekoälytuutorin avulla — ilmaiseksi
Kirjoita ja suorita oikeaa koodia selaimessa, saa välitöntä apua tekoälytuutorilta ympäri vuorokauden ja jatka siitä, mihin jäit, verkossa tai sovelluksessa.
- Kurssit
- 142
- Oppitunnit
- 568
Usein kysytyt kysymykset
Onko oppitunti ”Rinnakkaisuus xargs -P:llä ja taustatöillä” ilmainen?
Kyllä — voit lukea täällä verkossa kokonaan ilmaiseksi mitkä tahansa DevOps-bootcamp-oppimispolun 3 oppituntia, myös oppitunnin “Rinnakkaisuus xargs -P:llä ja taustatöillä”. Sen jälkeen CoddyKit PRO avaa kaikki oppitunnit sekä interaktiiviset harjoitukset sisäänrakennetulla koodieditorilla ja ympäri vuorokauden toimivalla tekoälytuutorilla. DevOps-bootcamp-kurssilla on yhteensä 4 oppituntia.
Mitä opin oppitunnilla ”Rinnakkaisuus xargs -P:llä ja taustatöillä”?
Suorita toisistaan riippumattomia tehtäviä samanaikaisesti xargsin rinnakkaistilalla ja hallituilla taustatyöjoukoilla. Harjoittelet DevOps-bootcamp-aihetta koodilla, jonka suoritat suoraan selaimessa. Ympäri vuorokauden käytettävissä oleva tekoälytuutori vastaa kysymyksiisi oppitunnin aikana.
Tarvitsenko kokemusta aloittaakseni DevOps-bootcamp-opiskelun?
Aiempi kokemus ei ole tarpeen. CoddyKitin DevOps-bootcamp-oppimispolku sopii vasta-alkajista edistyneisiin, joten voit aloittaa tästä tai alusta ja edetä omaan tahtiisi. Tämä on oppitunti 2/4.
Kuinka kauan ”Rinnakkaisuus xargs -P:llä ja taustatöillä”-oppitunnin suorittaminen kestää?
Useimmat CoddyKitin oppitunnit kestävät noin 5–10 minuuttia. Jokainen oppitunti on lyhyt ja interaktiivinen, joten edistyt tasaisesti ja voit jatkaa siitä, mihin jäit – sekä verkossa että sovelluksessa.
Voinko kirjoittaa ja suorittaa koodia tällä DevOps-bootcamp-oppitunnilla?
Kyllä. Jokainen DevOps-bootcamp-oppitunti sisältää sisäänrakennetun koodieditorin, joten voit kirjoittaa ja suorittaa oikeaa koodia suoraan selaimessa ja saada välitöntä palautetta tekoälyltä – paikallista asennusta ei tarvita.
Kaikki tämän kurssin oppitunnit
- Skriptien profilointi ja tarpeettomien alikuorien välttäminen
- Rinnakkaisuus xargs -P:llä ja taustatöillä
- Työkuormien orkestrointi GNU parallelilla
- Suoratoistoputket ja nimetyt putket läpimenon parantamiseen