Reputation: 3229
I use bash scripting to make use of multi cores by running C++ programs in the background using the &
symbol. (I'm a mathematician doing Monte Carlo Simulations).
This way I can run a C++ program in the background many times. For example:
for x in $(seq 1 1 100)
do
./program_name &
done
Sometimes program_name
will run fast, and sometimes it will run slow. This is random and impossible to know in advance. This prompts my question:
How do I make it, so that at any given time, no more than 4 jobs will be running simultaneously? Lets suppose 4 jobs are running at the moment. I want it so as soon as one finishes, the next one starts.
Upvotes: 2
Views: 85
Reputation: 60067
( #Start a subshell
N=4 #Specify number of jobs
for((i=1;i<100;i++))
do [ $((i%N)) = 0 ] && wait #Wait every N jobs
(sleep 1; echo "$i";)& #Some task
done
wait
)
The logic is pretty simple and it can be turned into a one-liner. You need a subshel to prevent interference with processes running in the background of the current session that we don't want to wait on.
Upvotes: 0
Reputation: 3229
The other solutions to this post are better than the one I am showing here. But I'd like to document my "less than perfect one" for completition. It doesn't have the ability to add a new job to the queue after one finishes... which is a bad thing because it creates idle time.
But the advantage is that you don't need to install anything. I'm hoping also that this is going to be less bug prone.
count=1 # current number of jobs processing
j=4 ## maximum number of jobs
for x in $(seq 1 1 10)
do
echo Currently running programe $x
## CPP code goes here
sleep $x & ## Pretend it takes x seconds to complete
count=$((count+1)) ## add one to the no. jobs running
if [ "$count" -gt "$j" ]; then
echo "Waiting for jobs to finish"
wait
count=1
fi
done
A clearly inefficient method, and I welcome any improvements.
Upvotes: 1
Reputation: 123490
On GNU, FreeBSD, and OSX you can use xargs
:
echo {1..100} | xargs -n 1 -P 4 ./program_name
Alternatively, you can install and use GNU parallel, which is made for exactly this kind of thing (for 4 jobs rather than 1 job/core, add -j 4
):
parallel --gnu ./program_name ::: {1..100}
Upvotes: 1