#!/bin/bash
# set -x # debug version
N=${1:-123}
n=${2:-45}
workers=${workers:-${3:-10}}
((workers < 1)) && ((workers = 1))
((workers > 20)) && ((workers = 20))
((min=100000000000000)) #set min to some garbage value
work() {
for i in ${*}; do
for (( j=1; j<=${n}; j++ )); do
val=$(/path/to/a.out)
val2=$(echo ${val} | bc)
(( val2 < min )) && (( min = val2 ));
done
echo ${min}
# # debug version
# echo ${i} ${j} ${min}
done
}
# --
arr=($(
seq ${N} | xargs -n$[N/workers + 1] | while read i; do
work ${i} &
done
wait
))
echo ${arr[*]}
# --
# # debug version
# seq ${N} | xargs -t -n$[N/workers + 1] | while read i; do
# work ${i} &
# done
# wait
Always use workers when spawning a parameterized numbers of processes and limit the maximum number of workers that can spawn.
xargs -n | while read
is a simple means of iterating lists in batches.
seq
creates a list of numbers from 1 to N.
xargs -n
breaks that list into N/workers+1 batches.
- e.g. N=100 workers=10 will produces 10 lines of up to 11 numbers from 1 to 100.
while read i
reads each line of numbers.
work ${i} &
just calls the work
function with ${i}
batch of numbers.
To debug i've added commented-out debug code. Just replace the echo
with the debug version and the code between # --
with its debug version and you can see how it works on batches. Uncomment set -x
for a more detailed debug output which you might want to redirect to a file.
Just run the debug version with different parameters to watch how it operates:
parallel.sh 223 5 1
parallel.sh 223 5 5
parallel.sh 223 5 10
parallel.sh 223 5 20
Disclaimer: This code doesn't synchronize the min
value between worker processes. Obtaining the minimum value isn't a horrible exercise. This'll probably do:
parallel.sh 223 5 20 | tr ' ' '\n' | sort -n | head -1
Or just add the same to the script itself:
echo ${arr[*]} | tr ' ' '\n' | sort -n | head -1