After a few days of intensive research I found two methods of lowering the cpu usage for processes. Generally if you want to lower the cpu usage of the entire machine, there are probably some programs which use the most long-lasting cpu and you should restrict those rather than burden the entire machine. And if you doing this to save battery life then you might also want to control the hardware's power usage with e.g. tuned or powertop, most distros have tools to help you with that.
- Stop/Continue signals
Signals were around since UNIX. You send a SIGSTOP or SIGTSTP to a process (the difference is the former may crash a process if it must do cleanup work, processes are not forced to stop at the latter, use the one that suits your process) to pause it (freeing the CPU and possibly lowering temperature). Then you send a SIGCONT to the process to resume it, taking the CPU. This method will make a series of "spikes" on the cpu graph and will stop the processor from overheating because you're not giving it enough time for that by pausing processes.
A consequence of this method is that these pauses are not smooth, meaning video playing and even web browsing won't be smooth either, so you may want to use this method with shell commands (multi-process programs or commands like Google Chrome or make won't work well with this method either). Obviously, it's not recommended to pause/resume system processes like systemd.
Although you could do this manually, cpulimit is a nice small program that uses this method (it uses SIGSTOP/SIGCONT). Contrary to the description, the cpu % you specify is between 0 and 100 even if you have multiple cores. And you can always suspend a job in the terminal with Ctrl-Z.
- cpupower (highly recommended)
This one is built in the Linux kernel so most distros should provide it (get it here if you don't have it). This command-line utility manages the CPU frequency so it pretty much controls the entire cpu using governor states (e.g., performance, powersave, etc.), it can also do other things. Unlike the pause/resume method, processes are much smoother with this. You'll need to set the maximum frequency for the processor.
cpupower frequency-info to see your available processor states.
- As root, type
cpupower frequency-set -u <frequency>, start with the lowest one you have and then try to find the highest frequency that doesn't overheat.
- (This is optional) If you want, you can install the lm_sensors package which allows you to see your system temperature. Then run
sensors-detect and answer 'yes' to all the questions. Last, run
sensors to see the current and critical (beyond which the system overheats) temperatures.
At this point the current temperature should be much lower now.
Be aware though some performance-intensive programs like games might hang after typing the above command, if you get a popup window with that message you should wait for the program rather than force quit. Note you have to type this command every time the system reboots (unless you can get it to run automatically).
See this and this for more information on cpupower.