DevOps-bootcamp · Oppitunti

Rinnakkaisuus xargs -P:llä ja taustatöillä

Suorita toisistaan riippumattomia tehtäviä samanaikaisesti xargsin rinnakkaistilalla ja hallituilla taustatyöjoukoilla.

Oppitunti 2/413 vaihetta

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_demo

xargs -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_demo

Sopivan -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_usage ja 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 -sSO

Taustatyö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_dl

find-, 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_demo

Nopeutuksen 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 -n yhdessä laskurin kanssa samanaikaisuuden rajoittamiseen.

Tärkeät säännöt jatkoa varten:

  • Viekää shell-funktiot komennolla export -f ennen 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
Aloita maksutta

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

  1. Skriptien profilointi ja tarpeettomien alikuorien välttäminen
  2. Rinnakkaisuus xargs -P:llä ja taustatöillä
  3. Työkuormien orkestrointi GNU parallelilla
  4. Suoratoistoputket ja nimetyt putket läpimenon parantamiseen
← Takaisin: DevOps-bootcamp