I had trouble with @PSkocik's solution. My system does not have GNU Parallel available as a package and sem threw an exception when I built and ran it manually. I then tried the FIFO semaphore example as well which also threw some other errors regarding communication.
@eyeApps suggested xargs but I didn't know how to make it work with my complex use case (examples would be welcome).
Here is my solution for parallel jobs which process up to N jobs at a time as configured by _jobs_set_max_parallel:
_lib_jobs.sh:
function _jobs_get_count_e {
jobs -r | wc -l | tr -d " "
}
function _jobs_set_max_parallel {
g_jobs_max_jobs=$1
}
function _jobs_get_max_parallel_e {
[[ $g_jobs_max_jobs ]] && {
echo $g_jobs_max_jobs
returnecho 0
}
echo 1
}
function _jobs_is_parallel_available_r() {
(( $(_jobs_get_count_e) < $g_jobs_max_jobs )) &&
return 0
return 1
}
function _jobs_wait_parallel() {
# Sleep between available jobs
while true; do
_jobs_is_parallel_available_r &&
break
sleep 0.1s
done
}
function _jobs_wait() {
wait
}
Example usage:
#!/bin/bash
source "_lib_jobs.sh"
_jobs_set_max_parallel 3
# Run 10 jobs in parallel with varying amounts of work
for a in {1..10}; do
_jobs_wait_parallel
# Sleep between 1-2 seconds to simulate busy work
sleep_delay=$(echo "scale=1; $(shuf -i 10-20 -n 1)/10" | bc -l)
( ### ASYNC
echo $a
sleep ${sleep_delay}s
) &
done
# Visualize jobs
while true; do
n_jobs=$(_jobs_get_count_e)
[[ $n_jobs = 0 ]] &&
break
sleep 0.1s
done