This is probably very old news for many, but I just found a nifty little program for the first time: cpulimit
.
I convert a lot of video files. A favourite source supplies only .FLV, but some family members are Apple-bound and require .MOV, so I convert the videos using avconv
and store the results on our fileserver.
It had annoyed me for some time that while avconv
was running on my system, I was effectively prevented from doing anything else. The window manager became jerky, froze for several seconds at a time, video playback was unusably jerky, sometimes stopping for many seconds at a time, or the image would lose sync with the sound. Even the mouse sometimes stopped being responsive for a second or two.
Using top, I saw that avconv
was using 150% of the CPU (I have a dual-core computer), sometimes more. I tried using renice
to control avconv
‘s excesses, but even with the avconv
process set to a nice value of 19, the high CPU usage and symptoms continued.
Finally it all got too much and I went looking for a solution – and found cpulimit
.
This delightfully simple little program lets you specify a process by name or ID, and what percentage of total processor power that process is allowed to use. I use it now on avconv
, and avconv
now runs a bit more slowly, while everything else (including me) keeps working. The really cool thing is that it applies to anything called avconv
, for as long as it (cpulimit
) is running – so even though my batch conversion script kicks off many copies of avconv
(sequentially), all of them are tamed by one instance of cpulimit
:
cpulimit -e aconv -l 45 > /dev/null 2>&1
Not only that, if there is nothing called avconv
running, cpulimit
will wait until there is – then control it. This means I can put the above invocation into my script anywhere before the loop that starts avconv
; cpulimit
will start up and wait until avconv
starts, then limit it.
The same applies if you specify a process ID to cpulimit
– if the process ID doesn’t yet exist, cpulimit
will wait until it does. In short, you don’t have to apply cpulimit
to a running process, which in turn means that you don’t have to figure out process IDs in order to use it.
Because cpulimit
will wait indefinitely for process to start, it’s important to kill it when it is no longer needed, especially if you invoked it on a PID, because that PID may be re-used after a while. In my scripts, the code looks something like this:
... cpulimit -e aconv -l 45 > /dev/null 2>1 CPULIMITPID=$! ... kill -TERM $CPULIMITPID ....
cpulimit
doesn’t seem clever enough to handle multiple simultaneous instances though. When I start a second instance of avconv
, it quickly runs up to 110% of CPU or more, while the first instance remains at around 45%. Possibly in such cases the specific PIDs need to be controlled. But it’s still very useful.
cpulimit
– highly recommended!
you should look into the nice and renice command line tools to set the nice level of avconv instead: let it use as much cpu as currently is idle and available…
As mentioned in my article, I did try renice, but it doesn’t work as expected. I’m not sure why not, since from the description of what it does, you’d expect renice to be exactly the right tool for this job.
Thank you!