Posteriormente a buscar en varios repositorios y páginas al final nos hemos encontrado la respuesta que te compartimos aquí.
Solución:
Tarea de muestra
task()
sleep 0.5; echo "$1";
Ejecuciones secuenciales
for thing in a b c d e f g; do
task "$thing"
done
carreras paralelas
for thing in a b c d e f g; do
task "$thing" &
done
Corridas paralelas en lotes de N-procesos
N=4
(
for thing in a b c d e f g; do
((i=i%N)); ((i++==0)) && wait
task "$thing" &
done
)
También es posible usar FIFO como semáforos y usarlos para garantizar que se generen nuevos procesos lo antes posible y que no se ejecuten más de N procesos al mismo tiempo. Pero requiere más código.
N procesos con un semáforo basado en FIFO:
# initialize a semaphore with a given number of tokens
open_sem()
mkfifo pipe-$$
exec 3<>pipe-$$
rm pipe-$$
local i=$1
for((;i>0;i--)); do
printf %s 000 >&3
done
# run the given command asynchronously and pop/push tokens
run_with_lock()
N=4
open_sem $N
for thing in a..g; do
run_with_lock task $thing
done
Explicación:
Usamos el descriptor de archivo 3 como un semáforo presionando (=printf
) y hacer estallar (=read
) fichas ('000'
). Al presionar el código de retorno de las tareas ejecutadas, podemos abortar si algo salió mal.
¿Por qué no los bifurca (también conocido como fondo)?
foo ()
local run=$1
fsl5.0-flirt -in $kar"deformed.nii.gz" -ref normtemp.nii.gz -omat $run".norm1.mat" -bins 256 -cost corratio -searchrx -90 90 -searchry -90 90 -searchrz -90 90 -dof 12
fsl5.0-flirt -in $run".poststats.nii.gz" -ref $kar"deformed.nii.gz" -omat $run".norm2.mat" -bins 256 -cost corratio -searchrx -90 90 -searchry -90 90 -searchrz -90 90 -dof 12
fsl5.0-convert_xfm -concat $run".norm1.mat" -omat $run".norm.mat" $run".norm2.mat"
fsl5.0-flirt -in $run".poststats.nii.gz" -ref normtemp.nii.gz -out $PWD/normFunc/$run".norm.nii.gz" -applyxfm -init $run".norm.mat" -interp trilinear
for run in $runList; do foo "$run" & done
En caso de que no esté claro, la parte importante está aquí:
for run in $runList; do foo "$run" & done
^
Haciendo que la función se ejecute en un shell bifurcado en segundo plano. Eso es paralelo.
for stuff in things
do
( something
with
stuff ) &
done
wait # for all the something with stuff
Si realmente funciona depende de tus comandos; No estoy familiarizado con ellos. El rm *.mat
parece un poco propenso a conflictos si se ejecuta en paralelo…
Al final de la post puedes encontrar las críticas de otros desarrolladores, tú de igual manera tienes la habilidad dejar el tuyo si te apetece.