2010-03-11 22 views
60

Me gustaría introducir la característica multithreading en mi script de shell.Multithreading en Bash

Tengo un script que llama a la función read_cfg() con diferentes argumentos. Cada una de estas llamadas a funciones es independiente.

Sería posible crear una instancia de estas llamadas a funciones (no scripts) en paralelo. Por favor, ¿cómo podemos lograr eso ...?

+0

Esto no es multihilo - es multiproceso. Cada instancia se ejecuta en un proceso distinto, copiado del original con 'fork()'. Estos procesos, a diferencia de los hilos, tienen sus propias tablas de descriptores de archivos, y su memoria es de copia sobre escritura (por lo tanto, cuando cambian el valor de una variable, el proceso principal no la ve). –

Respuesta

127

Claro, sólo tiene que añadir & después del comando:

read_cfg cfgA & 
read_cfg cfgB & 
read_cfg cfgC & 
wait 

todos esos puestos de trabajo se ejecute en segundo plano al mismo tiempo. El comando opcional wait esperará a que finalicen todos los trabajos.

Cada comando se ejecutará en un proceso separado, por lo que técnicamente no es "multihilo", pero creo que resuelve su problema.

+6

Debe leer la diferencia entre el proceso y el hilo. Lo que usted propone no es multihebra, implica procesos separados para cada comando. – TomTom

+24

@TomTom: Ciertamente sé la diferencia entre procesos e hilos. Si ve a través de la elección de las palabras de OP, creo que simplemente está preguntando si es posible ejecutar los comandos en paralelo (lo cual es posible). Agregué una nota sobre esto para aclarar. – Martin

19

El control del trabajo de Bash implica múltiples procesos, no múltiples subprocesos.

Puede ejecutar un comando en segundo plano con el sufijo &.

Puede esperar la finalización de un comando de fondo con el comando wait.

Puede ejecutar varios comandos en paralelo separándolos con |. Esto también proporciona un mecanismo de sincronización, ya que stdout de un comando a la izquierda de | está conectado a stdin of command a la derecha.

23

Puede ejecutar varias copias de su secuencia de comandos en paralelo, cada copia para diferentes datos de entrada, p. Ej. para procesar todos los archivos * .cfg en 4 núcleos:

ls *.cfg | xargs -P 4 -n 1 read_cfg.sh 

El guión read_cfg.sh sólo necesita un parámetros (como cumplir por -n)

+2

solo una nota que debe especificar la ruta completa a 'read_cfg.sh' o' xargs' dirá que no puede encontrar el archivo. – Jeshurun

+0

Es mejor usar 'printf '% s \ 0' * .cfg | xargs -0 ... '- de esa manera esto funciona con nombres de archivos con espacios, caracteres no imprimibles, etc. Ver también [Por qué no se debe analizar el resultado de ls (1)] (http://mywiki.wooledge.org/ParsingLs). –