cpulimit命令用于限制Linux上特定进程的CPU使用率,确保其不超过设定的阈值。这对于管理系统资源和防止单个进程独占CPU时间特别有用,因为CPU独占可能会降低整体系统性能。通过指定所需的CPU使用率限制百分比,用户可以对正在运行的进程应用约束,或在受控CPU消耗下启动新进程。该工具通过向目标进程发送SIGSTOP和SIGCONT信号来暂停和恢复进程,从而维持设定的使用率限制。

前置说明

本教程已在Ubuntu 24.04上测试,但也适用于较旧的Ubuntu版本。

安装CPULimit

首先,我们需要安装cpulimit:

sudo apt update
sudo apt install cpulimit

限制CPU使用率

现在我们将测试限制CPU使用率的工具。为此,我们将先检查不使用cpulimit时的CPU使用率,然后再应用cpulimit来评估效果。让我们通过示例来说明。

1. 单核CPU上的使用示例:

以下是在单核CPU上使用应用程序消耗CPU的示例:

dd if=/dev/zero of=/dev/null &

然后使用以下命令查看CPU使用率:

top
top - 11:24:18 up 49 min,  1 user,  load average: 0.94, 1.02, 1.79
Tasks: 249 total,   2 running, 247 sleeping,   0 stopped,   0 zombie
%Cpu(s): 13.4 us, 11.6 sy,  0.0 ni, 74.9 id,  0.0 wa,  0.1 hi,  0.0 si,  0.0 st
KiB Mem:   1010540 total,   271652 used,   738888 free,    21760 buffers
KiB Swap:  1048572 total,        0 used,  1048572 free.   158204 cached Mem

  PID USER      PR  NI    VIRT    RES    SHR S  %CPU %MEM     TIME+ COMMAND
 1850 root      20   0    7224    616    520 R 100.0  0.1   1:20.33 dd
 1851 root      20   0   24952   1756   1180 R   0.3  0.2   0:00.03 top
    1 root      20   0   33480   2776   1456 S   0.0  0.3   0:05.31 init
    2 root      20   0       0      0      0 S   0.0  0.0   0:00.01 kthreadd

如上所示,CPU使用率已达到100%。现在我们将使用cpulimit来限制CPU使用率。我们可以使用fg命令将此进程调到前台,然后使用CTRL+C取消它:

fg

现在我们可以测试cpulimit是否正常工作。如下所示进行测试:

cpulimit -l 30 dd if=/dev/zero of=/dev/null &
root@server1:~# cpulimit -l 30 dd if=/dev/zero of=/dev/null &
[1] 1852
root@server1:~# Process 1853 detected
[1]+  Done                    cpulimit -l 30 dd if=/dev/zero of=/dev/null
root@server1:~#

现在使用top命令查看CPU使用率:

top
top - 11:30:54 up 55 min,  1 user,  load average: 0.20, 0.58, 1.34
Tasks: 250 total,   2 running, 247 sleeping,   1 stopped,   0 zombie
%Cpu(s):  4.5 us,  4.1 sy,  0.0 ni, 91.4 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
KiB Mem:   1010540 total,   271944 used,   738596 free,    21816 buffers
KiB Swap:  1048572 total,        0 used,  1048572 free.   158212 cached Mem

PID USER      PR  NI    VIRT    RES    SHR S  %CPU %MEM     TIME+ COMMAND
1853 root      20   0    7224    612    520 T  33.8  0.1   0:35.53 dd
    1 root      20   0   33480   2776   1456 S   0.0  0.3   0:05.37 init
    2 root      20   0       0      0      0 S   0.0  0.0   0:00.01 kthreadd
    3 root      20   0       0      0      0 S   0.0  0.0   0:00.02 ksoftirqd/0
    4 root      20   0       0      0      0 S   0.0  0.0   0:00.00 kworker/0:0

可以看到CPU使用率已从100%降至33.8%,接近30%。因此我们成功验证了cpulimit工具可以在单核Ubuntu系统中限制CPU使用率。

2. 多核CPU上的使用示例:

要查看CPU核心数,使用以下命令:

nproc

在本例中,CPU核心数为4。

现在我们将在不使用cpulimit的情况下检查所有4个核心上的CPU使用率:

for j in `seq 1 4`; do dd if=/dev/zero of=/dev/null & done
root@server1:~# for j in `seq 1 4`; do dd if=/dev/zero of=/dev/null & done
[1] 1263
[2] 1264
[3] 1265
[4] 1266
root@server1:~#

现在使用top命令查看CPU使用率:

top
top - 11:47:45 up 4 min,  1 user,  load average: 3.63, 1.53, 0.57
Tasks: 290 total,   5 running, 285 sleeping,   0 stopped,   0 zombie
%Cpu0 : 48.3 us, 51.3 sy,  0.0 ni,  0.0 id,  0.0 wa,  0.3 hi,  0.0 si,  0.0 st
%Cpu1 : 47.8 us, 52.2 sy,  0.0 ni,  0.0 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
%Cpu2 : 53.3 us, 46.4 sy,  0.0 ni,  0.0 id,  0.0 wa,  0.3 hi,  0.0 si,  0.0 st
%Cpu3 : 52.0 us, 48.0 sy,  0.0 ni,  0.0 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
KiB Mem:   1010540 total,   209712 used,   800828 free,    20276 buffers
KiB Swap:  1048572 total,        0 used,  1048572 free.    93632 cached Mem

PID USER      PR  NI    VIRT    RES    SHR S  %CPU %MEM     TIME+ COMMAND
1263 root      20   0    7224    612    520 R 100.0  0.1   2:21.40 dd
1264 root      20   0    7224    616    520 R 100.0 0.1   2:21.41 dd
1265 root      20   0    7224    612    520 R  99.0  0.1   2:21.03 dd
1266 root      20   0    7224    616    520 R  98.0 0.1   2:20.82 dd

dd命令几乎消耗了所有核心100%的CPU。接下来我们将使用cpulimit工具测试。首先终止之前的dd进程:

killall dd
root@server1:~# killall dd
[1]   Terminated              dd if=/dev/zero of=/dev/null
[3]-  Terminated              dd if=/dev/zero of=/dev/null
[2]-  Terminated              dd if=/dev/zero of=/dev/null
[4]+  Terminated              dd if=/dev/zero of=/dev/null
root@server1:~#

现在使用cpulimit运行相同的命令:

for j in `seq 1 4`; do cpulimit -l 20 dd if=/dev/zero of=/dev/null & done
root@server1:~# for j in `seq 1 4`; do cpulimit -l 20 dd if=/dev/zero of=/dev/null & done
[1] 1429
[2] 1430
[3] 1431
[4] 1432
root@server1:~# Process 1434 detected
Process 1433 detected
Process 1437 detected
Process 1439 detected
[1]   Done                    cpulimit -l 20 dd if=/dev/zero of=/dev/null
[2]   Done                    cpulimit -l 20 dd if=/dev/zero of=/dev/null
[3]-  Done                    cpulimit -l 20 dd if=/dev/zero of=/dev/null
[4]+  Done                    cpulimit -l 20 dd if=/dev/zero of=/dev/null
root@server1:~#

现在查看使用cpulimit后的CPU使用率:

top
top - 11:59:10 up 16 min,  2 users,  load average: 0.47, 0.71, 0.81
Tasks: 256 total,   2 running, 251 sleeping,   3 stopped,   0 zombie
%Cpu0 :  2.0 us,  2.0 sy,  0.0 ni, 96.0 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
%Cpu1 : 26.2 us, 22.8 sy,  0.0 ni, 50.7 id,  0.0 wa,  0.3 hi,  0.0 si,  0.0 st
%Cpu2 : 14.0 us, 12.3 sy,  0.0 ni, 73.8 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
%Cpu3 : 13.3 us, 11.6 sy,  0.0 ni, 75.1 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
KiB Mem:   1010540 total,   204064 used,   806476 free,    20408 buffers
KiB Swap:  1048572 total,        0 used,  1048572 free.    98340 cached Mem

PID USER      PR  NI    VIRT    RES    SHR S  %CPU %MEM     TIME+ COMMAND
1433 root      20   0    7224    612    520 T  28.2 0.1   0:12.00 dd
1439 root      20   0    7224    616    520 R  26.6 0.1   0:12.13 dd
1434 root      20   0    7224    612    520 T  25.3 0.1   0:11.97 dd
1437 root      20   0    7224    612    516 T  22.9  0.1   0:11.93 dd

如上所示,多核CPU的使用率已从100%降至约20%。

恭喜!我们已成功测试了在Ubuntu中使用cpulimit限制CPU使用率。