Paralelismo con xargs -P y trabajos en segundo plano
Ejecute tareas independientes de forma simultánea mediante el modo paralelo de xargs y grupos administrados de trabajos en segundo plano.
Paralelismo con xargs -P y trabajos en segundo plano es una lección gratuita de DevOps Bootcamp en CoddyKit. Esta es la lección 2 de 4. Puedes leer la lección completa abajo gratuitamente — luego la practicas en el navegador con un editor de código integrado y un tutor de IA 24/7. Forma parte de la ruta de aprendizaje de DevOps Bootcamp, y tu progreso se sincroniza en la web y la app de CoddyKit. El curso de DevOps Bootcamp incluye 4 lecciones en total.
Por qué la ejecución secuencial es lenta
Cuando ejecuta comandos uno tras otro en un script de shell, deja los núcleos de la CPU inactivos. Considere cambiar el tamaño de 500 imágenes: cada llamada a convert usa un núcleo mientras los otros siete permanecen inactivos.
El paralelismo resuelve este problema al distribuir varias tareas simultáneamente. En Bash, dos herramientas principales facilitan esta tarea:
- xargs -P: distribuye una lista de entradas entre N procesos de trabajo paralelos
- Trabajos en segundo plano (&) + wait: inicia procesos manualmente y los espera
Esta lección abarca ambos enfoques para que pueda elegir la herramienta adecuada en cada situación.
Repaso de los conceptos básicos de xargs
Antes de añadir paralelismo, recuerde cómo funciona xargs. Lee elementos de stdin y los pasa como argumentos a un comando.
La opción -I {} permite colocar el elemento de entrada en cualquier parte de la cadena de comandos, no solo al final.
El ejemplo siguiente convierte a mayúsculas cada archivo .txt mediante tr. Cada archivo se procesa uno a uno (línea base secuencial).
#!/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_demoIntroducción a xargs -P
Añada la opción -P N a xargs para ejecutar hasta N procesos en paralelo. xargs administra automáticamente el conjunto de procesos de trabajo: cuando se libera un puesto, el siguiente elemento comienza de inmediato.
-P 0: inicia tantos procesos como entradas haya (úselo con precaución en listas grandes)-P 4: mantiene como máximo 4 procesos de trabajo en ejecución en cada momento-n 1: envía exactamente un elemento de entrada por proceso invocado (una opción complementaria habitual)
Juntas, -n 1 -P 4 forman el patrón más habitual: un elemento por proceso de trabajo y cuatro procesos simultáneos.
#!/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 "$@"' _Procesamiento paralelo de archivos
Un caso de uso práctico es comprimir muchos archivos de registro simultáneamente. Sin -P, cada llamada a gzip bloquea la siguiente. Con -P 8, se ejecutan hasta ocho compresiones a la vez y se saturan todos los núcleos de la CPU.
Observe que -n 1 garantiza que cada proceso de trabajo paralelo reciba exactamente un nombre de archivo, algo esencial cuando los nombres pueden contener espacios (combínelo con -d '\n' o con -print0 / -0 para mayor seguridad).
#!/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_demoCómo elegir el valor adecuado de -P
Establecer -P demasiado bajo desaprovecha núcleos; establecerlo demasiado alto provoca thrashing. Un buen punto de partida es el número de núcleos lógicos de la CPU:
- Tareas limitadas por la CPU (compresión, codificación):
-P $(nproc) - Tareas limitadas por E/S (llamadas de red, lecturas de disco):
-P $(($(nproc) * 4))o un valor superior, porque los procesos de trabajo pasan la mayor parte del tiempo esperando - Tareas limitadas por la memoria: calcule
available_RAM / task_RAM_usagey establezca ahí el límite
nproc devuelve el número de unidades de procesamiento disponibles, por lo que constituye una alternativa portable a los números codificados manualmente.
#!/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 -sSOTrabajos en segundo plano con &
A veces necesita más control del que ofrece xargs: gestión de errores por trabajo, listas dinámicas o estructuras de argumentos complejas. Use el operador de segundo plano incorporado del shell, &, para iniciar trabajos manualmente.
Añadir & a cualquier comando devuelve inmediatamente el control al script. El proceso hijo se ejecuta en segundo plano mientras el proceso padre continúa. Llame a wait al final para bloquear la ejecución hasta que terminen todos los procesos hijos.
#!/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."Limitar la concurrencia con un conjunto de trabajos
Iniciar todos los trabajos a la vez con & puede agotar la memoria cuando la lista es grande. Un conjunto de trabajos mantiene como máximo N trabajos en ejecución en cada momento:
- Después de iniciar cada trabajo, compruebe cuántos trabajos en segundo plano están activos mediante
jobs -r | wc -l - Si el recuento alcanza el límite, llame a
wait -n(Bash 4.3+) para esperar a que termine cualquier trabajo antes de iniciar el siguiente
Este patrón imita internamente el funcionamiento de xargs -P, pero le proporciona flexibilidad total para crear scripts alrededor de cada trabajo.
#!/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."Capturar códigos de salida de trabajos paralelos
Una cuestión fundamental de los trabajos en segundo plano es que, si falla un proceso hijo, el script padre no lo sabe automáticamente. Debe capturar el PID de cada proceso hijo y comprobar su estado de salida con wait <pid>.
El patrón siguiente almacena cada PID en un array y, después, recorre el array llamando a wait "$pid", que devuelve el código de salida de ese proceso hijo concreto.
#!/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; }Descargas paralelas con xargs -P
La E/S de red es un caso típico para usar un alto nivel de paralelismo: cada proceso de trabajo pasa la mayor parte del tiempo esperando los bytes. El ejemplo siguiente obtiene varias URL simultáneamente y guarda cada una en un archivo con un nombre único.
Opciones clave utilizadas:
-P 8: ocho procesos de curl simultáneos-n 1: una URL por invocación de curl--create-dirs -o: curl guarda el resultado en un nombre de archivo derivado
#!/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_dlCombinar find, xargs -P y funciones del shell
Para usar una función del shell de varias líneas con xargs, debe exportarla mediante export -f function_name y, después, invocarla dentro de xargs mediante bash -c 'function_name "$@"' _.
Este patrón permite utilizar toda la potencia de los scripts dentro de cada proceso de trabajo paralelo: registro, gestión de errores y lógica condicional, todo por elemento.
#!/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_demoMedir la aceleración con time
Mida siempre antes de afirmar que ha obtenido una mejora. Ejecute su comando paralelo con time y compárelo con la línea base secuencial. La aceleración real depende de:
- Independencia de las tareas: las tareas no deben compartir estado escribible sin bloqueos
- Coste adicional: el coste de iniciar procesos (aproximadamente 5-20 ms cada uno) es importante en tareas pequeñas
- Contención de recursos: la E/S de disco puede saturarse incluso antes que la CPU
A continuación se muestra un patrón de prueba sencillo: ejecútelo de forma secuencial y después en paralelo, y compare los tiempos de reloj de pared real.
#!/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' _Comprobación de conocimientos: comportamiento de xargs -P
Ponga a prueba su comprensión de la ejecución paralela con xargs -P.
Resumen de la lección
Ahora dispone de dos técnicas fiables para la ejecución paralela en Bash:
- xargs -n 1 -P N: el enfoque más sencillo; xargs administra automáticamente el conjunto de procesos de trabajo. Es la mejor opción cuando la entrada es una lista simple y cada elemento corresponde a un comando.
- Trabajos en segundo plano (&) + wait: ofrece control total mediante scripts y es esencial cuando necesita los PID de cada trabajo, entradas dinámicas o una gestión detallada de los códigos de salida. Use
wait -ncon un contador para limitar la concurrencia.
Reglas clave que debe recordar:
- Exporte las funciones del shell con
export -fantes de pasarlas mediantexargs - Use
-print0/-0para gestionar de forma segura los nombres de archivo con espacios - Capture los PID en un array y llame individualmente a
wait "$pid"para detectar errores - Realice pruebas con
time: el paralelismo solo ofrece ventajas cuando el coste adicional de las tareas supera el coste de iniciar procesos - Establezca
-P $(nproc)para cargas limitadas por la CPU y un múltiplo superior para cargas limitadas por E/S
Aprende DevOps Bootcamp con un tutor de IA — gratis
Escribe y ejecuta código real en tu navegador, obtén ayuda instantánea de un tutor de IA disponible 24/7 y continúa donde lo dejaste en la web o en la aplicación.
- Cursos
- 142
- Lecciones
- 568
Preguntas frecuentes
¿La lección «Paralelismo con xargs -P y trabajos en segundo plano» es gratis?
Sí — el texto completo de «Paralelismo con xargs -P y trabajos en segundo plano» es gratis para leer aquí en la web. Para practicarla de forma interactiva (editor de código integrado y tutor de IA 24/7) y desbloquear el resto del curso de DevOps Bootcamp, actualiza a CoddyKit PRO. El curso de DevOps Bootcamp incluye 4 lecciones en total.
¿Qué aprenderé en «Paralelismo con xargs -P y trabajos en segundo plano»?
Ejecute tareas independientes de forma simultánea mediante el modo paralelo de xargs y grupos administrados de trabajos en segundo plano. Practicas DevOps Bootcamp con código real que ejecutas directamente en el navegador, y un tutor de IA 24/7 responde tus preguntas mientras trabajas en la lección.
¿Necesito experiencia previa para empezar DevOps Bootcamp?
No se requiere experiencia previa. DevOps Bootcamp en CoddyKit está estructurado para principiantes hasta estudiantes avanzados, así que puedes empezar aquí o desde el inicio y avanzar a tu ritmo. Esta es la lección 2 de 4.
¿Cuánto tiempo toma la lección «Paralelismo con xargs -P y trabajos en segundo plano»?
La mayoría de las lecciones de CoddyKit toman alrededor de 5–10 minutos. Cada una es compacta e interactiva, así que avanzas constantemente y retomas exactamente por donde dejaste en la web y la app.
¿Puedo escribir y ejecutar código en esta lección de DevOps Bootcamp?
Sí. Cada lección de DevOps Bootcamp incluye un editor de código integrado, así que escribes y ejecutas código real directamente en tu navegador y obtienes retroalimentación instantánea de IA — sin configuración local necesaria.
Todas las lecciones de este curso
- Perfilado de scripts y cómo evitar subshells innecesarios
- Paralelismo con xargs -P y trabajos en segundo plano
- Orquestación de cargas de trabajo con GNU parallel
- Pipelines de streaming y tuberías con nombre para mejorar el rendimiento