Search code examples
bashtestingscriptingbackgroundstress

In Bash script, 'stress' application runs twice each time I call it. Causes memory leak


I'm trying to write a script to allow me to use the 'stress' application without tying up a CPU 100% of the time. I broke up the mem allocation and the CPU allocation into two separate 'stress' commands so that I could stress mem continuously while stressing CPU only 1/2 the time. For example,

#!/bin/bash
set -m

/usr/local/bin/stress --vm 1 --vm-bytes 100MB &
while [ thing that evaluates as true ]
do
  /usr/local/bin/stress --cpu 1 --timeout 5s
  /usr/bin/sleep 5s
done

echo "Running jobs at end of script are: `jobs -p`"
echo `jobs -p` | /usr/bin/xargs kill -9
echo "After trying to kill them, running jobs are now: `jobs -p`"

For some reason, though, when I do this I end up seeing that stress is actually called twice for each time I try to run it. This means that I end up getting two instances of stress allocating memory, and then two instances of stress that tie up a CPU, then stop, then tie it up, and stop, etc.

Further, when the while loop exits, my kill ends up only killing one of the two stress instances that was running in the background.

What I can see from the ps -ef command is that the parent pid of one 'stress' is the pid of the other 'stress'. So when the while loop exits, the kill I wrote only ends up killing one of these mem allocating stress instances, because the second isn't owned by the script.

Processes during the script's run:

linux:~ # ps -ef | egrep "stress|bash"
...
root     23776 20979  0 14:32 pts/0    00:00:00 /bin/bash ./base_case.sh
root     23785 23776  0 14:32 pts/0    00:00:00 stress --vm 1 --vm-bytes 100MB
root     23788 23785  0 14:32 pts/0    00:00:16 stress --vm 1 --vm-bytes 100MB
root     23802 23776  0 14:32 pts/0    00:00:00 stress --cpu 1 --timeout 5s
root     23803 23802  0 14:32 pts/0    00:00:01 stress --cpu 1 --timeout 5s
...

Script's output seems to imply that only one 'stress' is called each time:

linux:~ # ./base_case.sh 
stress: info: [23785] dispatching hogs: 0 cpu, 0 io, 1 vm, 0 hdd
stress: info: [23802] dispatching hogs: 1 cpu, 0 io, 0 vm, 0 hdd
stress: info: [23802] successful run completed in 5s
Running jobs at end of script are: 23785
./base_case.sh: line 14: 23785 Killed /usr/local/bin/stress --vm 1 --vm-bytes 100MB
After trying to kill them, running jobs are now: 

Processes after the script finishes:

linux:~ # ps -ef | egrep "stress|bash"
...
root     23788     1  0 14:32 pts/0    00:00:58 stress --vm 1 --vm-bytes 100MB
...

I'll avoid any jokes about cutting my stress in half, but I would really appreciate any tips that will stop me from doubling up on the stress applications that are called from my script (and causing a memory leak...). Thanks!


Solution

  • It's not creating two instances it's just creating a thread. You can see that the PID of you CPU stress call is 23802 and that is the parent PID for the second entry in the ps output.

    I recommend using htop with tree view (F5) there you can easily see the hierarchy. (maybe top has tree view as well)