How can I automatically kill the process with the highest CPU load?

There are a family of Unix commands that will probably serve you better if you're aware of them for this type of work.

  • pgrep
  • pkill
  • killall

You can use these tools to make your "attacks" more targeted, especially in situations where you know the misbehaving process by name(s).

killall

I have a recurring issue with Chrome where it eventually needs to be dealt with by killing it. I usually do this command to eradicate all of them.

$ killall chrome

pgrep & pkill

But I could do this as well, to deal with only the newest process:

# to list
$ pgrep -n chrome
23108

# to kill
$ pkill -n chrome

Killing based on your command line

You can also add the -f switch to reach those processes that have long path arguments that you'd rather match on, instead of just their executable's name.

For example, say I had these processes:

$ ps -eaf | grep some
saml     26624 26575  0 22:51 pts/44   00:00:00 some weird command
saml     26673 26624  0 22:51 pts/44   00:00:00 some weird command's friend
saml     26911 26673  8 22:54 pts/44   00:00:00 some weird command's friend

They're just Bash shells with their ARGV0 set to those names. Incidentally I made those processes using this trick:

$ (exec -a "some weird command name's friend" bash)

Going after friends

But say I have a lot of them, and I only want to go after a particular set of them because they have "friend" in their command lines. I could do this:

$ pgrep -f friend
26673
26911

Going after the youngest friend

And if there were a couple of them and I wanted to go after the newest, add the -n switch back into the mix:

$ pgrep -fn friend
26911

You can also use regular expressions when enlisting the -f switch, so these would work, for example:

$ pgrep -f "weird.*friend"
26673
26911

Displaying their names

You can double check the processes names using the -l switch:

$ pgrep -f "weird.*friend" -l
26673 some weird command's friend
26911 some weird command's friend

Controlling the output

Or tell pgrep to list the process IDs delimited using a comma (,):

$ pgrep -f "weird.*friend" -d,
26673,26911

You can do cool things like this:

$ ps -fp $(pgrep -f weird -d,)
UID        PID  PPID  C STIME TTY          TIME CMD
saml     26624 26575  0 22:51 pts/44   00:00:00 some weird command
saml     26673 26624  0 22:51 pts/44   00:00:00 some weird command's friend
saml     26911 26673  0 22:54 pts/44   00:00:00 some weird command's friend

So how do I kill the high CPU process?

I would use the above to be more selective in going after a high CPU process. You could use the approach of killing using these methods:

# newest guys
$ pkill -nf vlc ; pkill -nf opensnap

# kill all of these
$ killall vlc; killall opensnap

Look at their CPU loads:

$ top -b -n 1 | grep -E $(pgrep -f "weird.*friend" -d\|) | grep -v grep
26911  0.1  112m 106m 6408  848 4900 1512    0    0 S  20   0  0.0 some weird command's friend                                     
26673  0.1  112m 106m 6392  848 5020 1504    0    0 S  20   0  0.0 some weird command's friend 

Here I've changed the delimiter from a comma (,) aka. this switch -d,, to a pipe (|) aka. this switch -d\|, so that I can use it in a grep. Doing this will return the process IDs like this:

$ pgrep -f "weird.*friend" -d\|
26673|26911

We then insert these into the grep -E ... command so we can filter the output from top based on certain process IDs.

This might seem like a lot of bending backwards, but we now know with certainty that the process IDs we're using are only the ones related to a give process named "weird.*friend".

From here you can find the process with the highest CPU and kill it, if you really want to go that way.

A more targeted approach to high CPU

$ top -b -n 1 | grep -E $(pgrep -f "weird.*friend" -d\|) | \
    grep -v grep | sort -nk14,14 | tail -1
26911  0.1  112m 106m 6408  848 4900 1512    0    0 S  20   0  0.0 some weird command's friend                                     

The above shows the sorted output from top by the CPU column (14th). It's sorted from lowest to highest, so we take the last line (tail -1) which would be the highest CPU process of the "weird.*friend" processes.


The program "and", Auto-Nice Daemon can be set up to do something to that effect.

You set up a list with several specific known troublemakers and three levels of re-nicing (so that you can re-nice progressively harshly), but any of which could be to kill the process already, even though that would more usually be reserved as the last resort.

It's not always easy to regulate things so that you achieve a certain desired levels of CPU load, but there are other tools that may help (and help avoiding killing offending process as well, by preventing the offense), such as cpulimit, and already starting programs with nice and ionice.

Tags:

Process

Kill

Top