You might try executing each matlab instance in a separate backgrounded subshell, and then just calling wait
at the bottom of your outer loop.
Here's an example I came up with that (I think) solves both problems (i.e., how to wait for all instances to finish, and how to run each instance on a specific CPU):
#!/bin/bash
numCpus=$(grep -c ^processor /proc/cpuinfo) # I don't have nproc on my system
for cpu in $(seq 0 $((numCpus-1))); do
(
sleepSecs=$(( RANDOM % 10 + 1 ))
echo "Sleeping for $sleepSecs seconds on CPU $cpu..."
taskset -c $cpu sleep $sleepSecs
echo "Done sleeping on CPU $cpu."
) &
done
usleep 500 # This is just here to keep the output ordered correctly
echo "Waiting for subshells to finish..."
wait
echo "All subshells completed."
Each subshell is run in the background with the &
suffix and sleeps a random amount of time between 1 and 10 seconds. After spawning the subshells, calling wait
with no arguments causes the parent shell to wait for all subshells to complete. Note that this assumes you haven't spawned any other subshells prior to this point in the script. If you have, you'll have to keep track of the PIDs or job numbers of each of the subshells you want to wait on, and pass them as arguments to wait
.
Running this on my machine, I get something that looks like this:
Sleeping for 2 seconds on CPU 0...
Sleeping for 9 seconds on CPU 1...
Sleeping for 4 seconds on CPU 3...
Sleeping for 8 seconds on CPU 2...
Sleeping for 10 seconds on CPU 4...
Sleeping for 9 seconds on CPU 5...
Waiting for subshells to finish...
Done sleeping on CPU 0.
Done sleeping on CPU 3.
Done sleeping on CPU 2.
Done sleeping on CPU 5.
Done sleeping on CPU 1.
Done sleeping on CPU 4.
All subshells completed.
Edit: Of course, if you want a visual confirmation that each subshell is running on the intended CPU, you should have it do something other than sleep
, since sleep
(by design) doesn't eat CPU cycles, and so won't show up on your CPU monitor. You can still confirm by printing out the PID of each spawned subshell, and then verifying with ps
or top
what CPU they're running on. These commands don't show that information by default, but I'm sure there are options to get them to display it. Also, keep in mind that although taskset
lets you set a process' CPU affinity, there is no guarantee that the kernel will run it on that CPU, or that the kernel won't switch it over to another CPU. The CPU affinity is more like a suggestion to the kernel regarding which CPU to use.