Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Run cputhrottle for a list of applications in order to limit their CPU usage.
#!/bin/bash
# Run cputhrottle for a list of applications in order to limit their CPU usage.
# This script needs `pidof` and `cputhrottle` installed, which can be installed from homebrew.
# NOTE: This script was tested on MacOS only.
if [[ $EUID > 0 ]]; then
echo "Please run this script as root/sudo"
exit 1
fi
# Pass --kill as argument to kill all running cputhrottles
if [ $1 = "--kill" ]; then
echo "Looking for running cputhrottles..."
pids=`pidof cputhrottle`
for pid in ${pids}; do
echo "> Killing PID ${pid}"
sudo kill ${pid}
done
printf "Done!\n\n"
exit 0
fi
# Start cputhrottle if it's not running yet for the given PID
set_cpu_limit() {
pid=$1
cpu_limit=$2
if [[ "$pid" == "" || "$cpu_limit" == "" || $cpu_limit -lt 1 || $cpu_limit -gt 100 ]]; then
echo "! Invalid arguments: pid=$pid, cpu_limit=$cpu_limit"
return
fi
printf "> PID=${pid}, CPU=${cpu_limit}"
service_cpu=$(ps aux | grep "sudo cputhrottle $pid $cpu_limit" | grep -v grep | wc -l)
if [[ ! $service_cpu -gt 0 ]]; then
sudo cputhrottle $pid $cpu_limit &
printf "\n"
else
printf " [already running]\n"
fi
}
declare -a applications
# Syntax='application-name;max-cpu%(1-100)'
applications[0]='Chrome;50'
applications[1]='idea;65'
applications[2]='pycharm;40'
applications[3]='webstorm;40'
applications[4]='datagrip;40'
for i in "${applications[@]}"; do
app=(${i//;/ })
app_name=${app[0]}
cpu_limit=${app[1]}
printf "\nLooking for ${app_name}...\n"
pids=`pidof ${app}`
for pid in ${pids}; do
set_cpu_limit ${pid} ${cpu_limit}
done
done
printf "\nDone!\n"
printf "Run this script passing '--kill' as argument to remove all cputhrottles.\n\n"
@trudnai

This comment has been minimized.

Copy link

commented Jul 20, 2017

I believe there are couple of minor issues, especially when process name includes space. Also I think pidof should look for the $app_name, not the $app.

This is how I have corrected on my side (note the use of the quotation marks):

...
applications[5]='Backup and Sync;25'

for i in "${applications[@]}"; do
  IFS=';'; app=(${i}); unset IFS;
  app_name=${app[0]}
  cpu_limit=${app[1]}
  printf "\nLooking for ${app_name}...\n"
  pids=`pidof "${app_name}"`
  for pid in ${pids}; do
    set_cpu_limit ${pid} ${cpu_limit}
  done
done
....
@TheOtherDave

This comment has been minimized.

Copy link

commented Jun 16, 2018

Thanks! Now I can keep that stupid bird process from taking up %190 of my CPU

@jacobthejones

This comment has been minimized.

Copy link

commented Sep 6, 2018

Is there a way to catch new instances of the process and limit them? This only runs cputhrottle for processes that exist at the moment the script is first run.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.