三. 进程调度器
Linux内核具有进程调度器的功能.
它使得多个进程能够同时运行(准确来说,是看上去像是同时运行)
一般而言,我们是无法察觉调度器的存在的,下面是调度器的描述.
- 一个cpu同时只能运行一个进程
- 在同时运行多个进程时,每个进程都获得适当的时长.轮流在CPU上执行处理.
需要指出的是,在CPU主频发展受到限制后,出现了多核心来提升CPU,这导致每一个核心都会被识别为CPU.
系统识别出来的核心称为逻辑核心
在开启超线程技术hyper thread
技术后,每一个线程都被识别为一个逻辑CPU.
3.1 实验程序设计
在同时运行一个或多个消耗CPU时间执行处理的进程时,采集以下统计信息.
- 在某一个时间点运行在逻辑CPU上的进程是哪一个
- 每个进程运行的进度
程序设计如下
-
命令行参数,(n,total,resol)
参数 定义 n 同时运行的进程数量 total 程序运行总时长,单位毫秒 resol 采集信息的频率周期,单位毫秒/次 -
令n个进程同时运行,然后在全部进程金额数后结束父进程的运行,各个进程按照以下要求运行
-
在消耗total毫秒的cpu时间后结束运行
-
每resol毫秒记录一次以下三个指标
pid,进程编号
从程序开始运行到记录的时间点为止经过的时间
进程的进度
-
结束运行后,把统计信息用制表符隔开并逐行输出
-
3.2 实验程序的实现
代码如下
(base) [root@ecs0003 linux_pro]# vim sched.c
#include <sys/types.h>
#include <sys/wait.h>
#include <time.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <err.h>
#define NLOOP_FOR_ESTIMATION 1000000000UL
#define NSECS_PER_MSEC 1000000UL
#define NSECS_PER_SEC 1000000000UL
static inline long diff_nsec(struct timespec before, struct
timespec after)
{
return ((after.tv_sec * NSECS_PER_SEC + after.tv_nsec)- (before.tv_sec * NSECS_PER_SEC + before.tv_nsec));
}
static unsigned long loops_per_msec()
{
struct timespec before, after;
clock_gettime(CLOCK_MONOTONIC, &before);
unsigned long i;
for (i = 0; i < NLOOP_FOR_ESTIMATION; i++);
clock_gettime(CLOCK_MONOTONIC, &after);
int ret;
return NLOOP_FOR_ESTIMATION * NSECS_PER_MSEC / diff_nsec
(before, after);
}
static inline void load(unsigned long nloop)
{
unsigned long i;
for (i = 0; i < nloop; i++)
;
}
static void child_fn(int id, struct timespec *buf, int
nrecord, unsigned long nloop_per_resol,
struct timespec start)
{
int i;
for (i = 0; i < nrecord; i++){
struct timespec ts;
load(nloop_per_resol);
clock_gettime(CLOCK_MONOTONIC, &ts);
buf[i] = ts;
}
for (i = 0; i < nrecord; i++){
printf("%d\t%ld\t%d\n", id, diff_nsec(start, buf[i]) /
NSECS_PER_MSEC, (i+1) * 100 / nrecord);
}
exit(EXIT_SUCCESS);
}
static void parent_fn(int nproc)
{
int i;
for (i = 0; i < nproc; i++)
wait(NULL);
}
static pid_t *pids;
int main(int argc, char *argv[])
{
int ret = EXIT_FAILURE;
if (argc < 4){
fprintf(stderr, "usage: %s <nproc> <total[ms]> <resolution[ms]>\n", argv[0]);
exit(EXIT_FAILURE);
}
int nproc = atoi(argv[1]);
int total = atoi(argv[2]);
int resol = atoi(argv[3]);
if (nproc < 1){
fprintf(stderr, "<nproc>(%d) should be >= 1\n", nproc);
exit(EXIT_FAILURE);
}
if (total < 1){
fprintf(stderr, "<total>(%d) should be >= 1\n", total);
exit(EXIT_FAILURE);
}
if (resol < 1){
fprintf(stderr, "<resol>(%d) should be >= 1\n", resol);
exit(EXIT_FAILURE);
}
if (total % resol){
fprintf(stderr, "<total>(%d) should be multiple of <resolution>(%d)\n", total, resol);
exit(EXIT_FAILURE);
}
int nrecord = total / resol;
struct timespec *logbuf = malloc(nrecord * sizeof(struct timespec));
if (!logbuf)
err(EXIT_FAILURE, "malloc(logbuf) failed");
puts("estimating workload which takes just one milisecond");
unsigned long nloop_per_resol = loops_per_msec() * resol;
puts("end estimation");
fflush(stdout);
pids = malloc(nproc * sizeof(pid_t));
if (pids == NULL){
warn("malloc(pids) failed");
goto free_logbuf;
}
struct timespec start;
clock_gettime(CLOCK_MONOTONIC, &start);
int i, ncreated;
for (i = 0, ncreated = 0; i < nproc; i++, ncreated++){
pids[i] = fork();
if (pids[i] < 0){
goto wait_children;
} else if (pids[i] == 0){
// 子进程
child_fn(i, logbuf, nrecord, nloop_per_resol, start);
/* 不应该运行到这里*/
}
}
ret = EXIT_SUCCESS;
// 父进程
wait_children:
if (ret == EXIT_FAILURE)
for (i = 0; i < ncreated; i++)
if (kill(pids[i], SIGINT) < 0) warn("kill(%d) failed", pids[i]);
for (i = 0; i < ncreated; i++)
if (wait(NULL) < 0) warn("wait() failed.");
free_pids:
free(pids);
free_logbuf:
free(logbuf);
exit(ret);
}
编译
(base) [root@ecs0003 linux_pro]# cc -o sched sched.c
3.3 实验
结合上面的程序,进行如下3个实验
- A 运行1个进程时的情况
- B 运行2个进程时的情况
- C 运行4个进程时的情况
利用负载均衡(后述)功能,进程可以根据系统的负载转移逻辑CPU运行.
本实验为了准确,只能运行在指定的单个逻辑CPU上.可以通过taskset
命令实现.-c
参数指定逻辑CPU
(base) [root@ecs0003 linux_pro]# taskset -c 0 ./sched <n> <total> <resol>
上述命令的意思是,指定0号逻辑CPU运行 sched程序
可以使用使用重定向将结果打印到文件中进行详细分析,绘制图表
taskset -c 0 ./sched 1 100 1 > 1core_sched.log
-
实验A
(base) [root@ecs0003 linux_pro]# taskset -c 0 ./sched 1 100 1 estimating workload which takes just one milisecond end estimation 0 1 1 0 2 2 0 4 3 0 5 4 0 6 5 0 7 6 0 9 7 0 10 8 0 12 9 0 13 10 0 14 11 0 16 12 0 17 13 ............. 0 115 88 0 116 89 0 117 90 0 119 91 0 120 92 0 121 93 0 123 94 0 124 95 0 125 96 0 127 97 0 128 98 0 129 99 0 131 100
-
实验B
(base) [root@ecs0003 linux_pro]# taskset -c 0 ./sched 2 100 1 estimating workload which takes just one milisecond end estimation 0 2 1 0 4 2 0 5 3 0 7 4 0 8 5 0 10 6 0 12 7 0 26 8 0 27 9 0 29 10 0 30 11 0 31 12 0 32 13 0 33 14 0 35 15 .......................................................................... 0 234 89 0 236 90 0 237 91 0 238 92 0 240 93 0 241 94 0 243 95 0 244 96 0 246 97 0 260 98 0 261 99 0 263 100 ............................................................................. 1 14 1 1 15 2 1 17 3 1 18 4 1 20 5 1 21 6 1 23 7 1 24 8 1 38 9 1 40 10 1 41 11 1 42 12 ........................................................................... 1 225 83 1 226 84 1 228 85 1 229 86 1 230 87 1 232 88 1 246 89 1 247 90 1 249 91 1 250 92 1 252 93 1 253 94 1 254 95 1 256 96 1 257 97 1 259 98 1 264 99 1 266 100
- 2个进程(进程0与进程1) 在轮流使用cpu.换句话说,不是同时使用该逻辑CPU
- 2个进程获得的时间片几乎相同
-
实验C
(base) [root@ecs0003 linux_pro]# taskset -c 0 ./sched 4 100 1 estimating workload which takes just one milisecond end estimation 1 12 1 1 13 2 1 15 3 1 16 4 1 18 5 ............................... 1 521 97 1 522 98 1 523 99 1 525 100 2 27 1 2 28 2 2 30 3 2 31 4 2 33 5 2 34 6 2 35 7 .................................. 2 539 97 2 541 98 2 542 99 2 543 100 0 1 1 0 3 2 0 4 3 0 5 4 0 7 5 0 8 6 0 9 7 0 11 8 ..................... 0 480 96 0 545 97 0 547 98 0 548 99 0 549 100 3 38 1 3 39 2 3 41 3 3 42 4 3 44 5 3 45 6 3 46 7 .............................. 3 501 92 3 503 93 3 528 94 3 529 95 3 530 96 3 532 97 3 533 98 3 534 99 3 551 100
- 单位时间进度约为进程数量为1时的1/4.全部进程运行结束所消耗的时间约为进程数量为1时的4倍
3.4 思考
通过上面三个实验,我们得出以下结论:
- 不管同时运行多少进程,在任意时间点上,只能有一个进程运行在逻辑CPU上.
- 在逻辑CPU上运行多个进程时,它们将按轮询调度的方式循环运行,即所有进程按照顺序逐个运行,一轮过后,重新从第一个进程开始理轮流运行
- 每个进程被分配到的时间片的长度大体相等.
- 全部进程运行结束消耗的时间,随着进程数量的增加而等比增加.
3.5 上下文切换
上下文切换是指切换正在逻辑CPU上运行的进程.
- 当一个时间段被消耗完毕后,不管进程正在执行什么代码,都一定会发生上下文切换.
3.6 进程的状态
系统中有多少进程在运行,可以通过命令ps -ax
来查看.某个时间点上,系统大部分进程处于睡眠状态
进程的一部分状态如下
状态名 | 含义 |
---|---|
运行态 | 在逻辑CPU上运行 |
就绪态 | 进程具备运行条件,准备分配CPU时间 |
睡眠态 | 进程不准备运行,除非发生某事件.在此期间不消耗CPU时间 |
僵死状态 | 进程结束,等待父进程将其回收(Linux系统进程编号为1,所有的进程的根就是它) |
PROCESS STATE CODES
Here are the different values that the s, stat and state output specifiers (header "STAT" or "S") will display to describe the state of a process:D uninterruptible sleep (usually IO) 不间断睡眠,通常是IO等待 R running or runnable (on run queue) 正在运行(或者在运行的队列上) S interruptible sleep (waiting for an event to complete) 可中断的睡眠(等待事件完成,就像上图中的进程0,在进程1运行的时候,就进入了这种睡眠状态) T stopped by job control signal 被作业控制信号终止. t stopped by debugger during the tracing 在跟踪期间被调试器停止 W paging (not valid since the 2.6.xx kernel) 分页(内核版本2.6以后失效) X dead (should never be seen) 死掉(永远不会被看到的) Z defunct ("zombie") process, terminated but not reaped by its parent 失效的僵尸进程,已经终止,但是其父进程并未回收该进程.
For BSD formats and when the stat keyword is used, additional characters may be displayed:
对于
BSD
格式以及使用stat
关键字时,可能会显示其他字符: 一般使用top,ps -ax命令,状态码的第二个字符
< high-priority (not nice to other users) 高优先级(对其他用户不友好) N low-priority (nice to other users) 低优先级(对其他用户友好) L has pages locked into memory (for real-time and custom IO) 将页面锁定入内存(对于实时和客户端IO) s is a session leader 一个会话的leader l is multi-threaded (using CLONE_THREAD, like NPTL pthreads do) 是一个多线程进程(使用CLONE_THREAD,类NPTL父线程等系统包装函数) + is in the foreground process group 前台进程组中的进程
3.7 状态转换
进程各种状态之间的关联和转换
进程的状态以及逻辑CPU上执行的处理.多个进程在某个逻辑CPU核心上
如果只有一个进程运行在某个逻辑CPU核心上
3.8 空闲状态
在上图中,p0进程有一段事件没有在逻辑CPU0上运行.
在这一段时间内,逻辑CPU0会运行一个被称为空闲进程
的不执行任何处理的特殊进程.
空闲进程最简单的实现方式就是创建一个新进程.或者在唤醒处于睡眠态的进程之前执行无意义的循环(有点像用户态的自旋锁)
然而,这样是非常费电的,所以通常不会这样处理,而是使用特殊CPU指令,让其进入休眠,直到出现就绪状态的进程.
使用命令sar -P -ALL 1
可以每秒观察一次cpu空闲时间占比
[root@sx-v-scjx-dwzyywzt-sjk-pgk-0001 ~]# sar -P ALL 1
Linux 3.10.0-862.el7.x86_64 (sx-v-scjx-dwzyywzt-sjk-pgk-0001.novalocal) 07/24/2023 _x86_64_ (32 CPU)
09:29:29 AM CPU %user %nice %system %iowait %steal %idle
09:29:30 AM all 9.01 0.00 2.07 3.85 0.00 85.07
09:29:30 AM 0 1.00 0.00 0.00 5.00 0.00 94.00
09:29:30 AM 1 1.00 0.00 0.00 24.00 0.00 75.00
09:29:30 AM 2 85.86 0.00 0.00 0.00 0.00 14.14
09:29:30 AM 3 47.52 0.00 0.00 0.00 0.00 52.48
09:29:30 AM 4 0.00 0.00 0.00 0.00 0.00 100.00
09:29:30 AM 5 0.00 0.00 0.00 0.00 0.00 100.00
09:29:30 AM 6 18.00 0.00 11.00 0.00 0.00 71.00
09:29:30 AM 7 0.00 0.00 0.00 0.00 0.00 100.00
09:29:30 AM 8 0.00 0.00 0.00 0.00 0.00 100.00
09:29:30 AM 9 0.00 0.00 0.00 0.00 0.00 100.00
..............................................................................................................
Average: CPU %user %nice %system %iowait %steal %idle
Average: all 10.63 0.00 3.48 2.72 0.00 83.17
Average: 0 10.62 0.00 6.25 14.37 0.00 68.75
Average: 1 8.46 0.00 3.76 14.11 0.00 73.67
Average: 2 46.23 0.00 5.35 12.89 0.00 35.53
Average: 3 30.09 0.00 7.21 0.00 0.00 62.70
Average: 4 12.19 0.00 2.50 0.31 0.00 85.00
Average: 5 6.90 0.00 4.08 0.00 0.00 89.03
Average: 6 45.91 0.00 28.93 0.00 0.00 25.16
Average: 7 0.00 0.00 0.00 0.00 0.00 100.00
Average: 8 0.00 0.00 0.00 0.00 0.00 100.00
Average: 9 0.00 0.00 0.00 0.00 0.00 100.00
................................................................................................................
Average: 26 8.72 0.00 0.31 1.56 0.00 89.41
Average: 27 9.35 0.00 0.31 3.74 0.00 86.60
Average: 28 1.89 0.00 10.06 29.56 0.00 58.49
Average: 29 8.12 0.00 6.25 0.00 0.00 85.62
Average: 30 17.45 0.00 9.66 0.00 0.00 72.90
Average: 31 66.25 0.00 12.19 0.94 0.00 20.62
下面,我们编写一个有性能侵入性的python程序
while True:
pass
运行这个程序后再观察cpu的%ideal
项
(base) [root@ecs0003 linux_pro]# taskset -c 0 python loop.py &
[1] 160209
(base) [root@ecs0003 linux_pro]# sar -P ALL 1
Linux 3.10.0-862.el7.x86_64 (ecs0003.novalocal) 07/24/2023 _x86_64_ (16 CPU)
09:55:05 AM CPU %user %nice %system %iowait %steal %idle
09:55:06 AM all 9.71 0.00 1.69 0.19 0.00 88.41
09:55:06 AM 0 100.00 0.00 0.00 0.00 0.00 0.00
09:55:06 AM 1 9.00 0.00 5.00 0.00 0.00 86.00
09:55:06 AM 2 0.00 0.00 0.00 0.00 0.00 100.00
09:55:06 AM 3 0.99 0.00 1.98 0.99 0.00 96.04
09:55:06 AM 4 5.00 0.00 4.00 0.00 0.00 91.00
09:55:06 AM 5 5.00 0.00 3.00 0.00 0.00 92.00
09:55:06 AM 6 0.99 0.00 0.99 0.99 0.00 97.03
.............................................................................................
Average: CPU %user %nice %system %iowait %steal %idle
Average: all 9.14 0.00 1.00 0.51 0.00 89.35
Average: 0 100.00 0.00 0.00 0.00 0.00 0.00
Average: 1 3.07 0.00 1.71 0.00 0.00 95.22
Average: 2 0.00 0.00 0.00 0.00 0.00 100.00
Average: 3 0.34 0.00 1.71 0.34 0.00 97.61
Average: 4 5.80 0.00 4.10 1.37 0.00 88.74
Average: 5 6.48 0.00 3.07 1.02 0.00 89.42
...................................................
Average: 11 0.68 0.00 0.68 0.00 0.00 98.63
Average: 12 0.00 0.00 0.34 0.00 0.00 99.66
Average: 13 0.34 0.00 0.34 0.00 0.00 99.32
Average: 14 3.07 0.00 2.05 0.68 0.00 94.20
Average: 15 25.43 0.00 1.03 4.81 0.00 68.73
(base) [root@ecs0003 linux_pro]# kill 160209
可以看到0号cpu已经被占满了,%ideal时间为0了.
3.9 各种各样的状态转换
结合3.8的论证,逻辑CPU的实际状态可能更复杂一些
当某个逻辑CPU上只存在一个进程运行时
我们可以看到,在内核态的时间段内都完成了作业,进程切换为用户态进行输入,文件读取等操作的时候,进程在CPU上呈现就绪态.
当存在多个进程的时候,情况如图
看起来多进程是比较复杂的,但是核心就两条
- 逻辑CPU上同一时间只能运行一个进程
- 睡眠态的进程不会占用CPU时间.
3.10 吞吐量与延迟
CPU主频,吞吐量是CPU性能的两个重要衡量指标
- 吞吐量:单位时间内的总工作量.
- 延时:各种处理从开始到完成所耗费的时间.
吞吐量=处理完成的进程数量/耗费的时间
延迟=结束处理的时间-开始处理的时间
-
cpu的计算资源消耗的越多,空闲时间就越少.
-
在耗尽逻辑CPU的计算力后,所有逻辑CPU都不处于空闲状态后,不管增加多少进程,吞吐量都不会发生变化
-
随着进程数量的增加,延迟会越来越长
-
每个进程平均延迟是相等的.
为了避免多进程排队执行出现的不公平,才有了cpu时间分片的方法.
3.11 存在多个逻辑CPU时的调度
存在多个逻辑CPU的时候,如何进行调度呢?
调度器会运行一个被称为均衡负载或全局调度的功能.
简单说,负载均衡将进程分配给多个逻辑CPU.
下图演示逻辑CPU0,CPU1为空闲状态后,按顺序执行进程0-3的情况
很显然,增加CPU的逻辑核心,有助于提高吞吐量.
3.12 运行时间和执行时间
通过time
命令运行进程,就可以得到进程从开始到结束所经过的时间elaps
-
运行时间:
进程从开始运行到运行结束为止所经过的时间.类似于利用秒表从开始运行的时间点开始计时,一直测量到运行结束.
-
执行时间:
进程实际占用逻辑CPU的时长
两者关系如下图
我们使用[3.2 实验程序的实现](### 3.2 实验程序的实现)的程序sched,结合time命令来观察运行时间和执行时间.
-
逻辑CPU数量=1.进程数量=1
(base) [root@ecs0003 linux_pro]# time taskset -c 0 ./sched 1 10000 10000 estimating workload which takes just one milisecond end estimation 0 13054 100 real 0m13.172s user 0m13.142s sys 0m0.001s
- real的值为运行时间
- user+sys的时间是用户态+内核态的执行时间.
此例中用户独占CPU资源,因此在CPU0上的执行时间几乎等于运行时间.两者差出来的0.029,是
sched.c
中loops_per_msec()
这个预处理消耗了一部分事件.不入内核态,是因为很少发生中断事件,一直在用户态循环而已.所以sys的值几乎为0.
-
逻辑CPU数量=1,进程数量=2
(base) [root@ecs0003 linux_pro]# time taskset -c 0 ./sched 2 10000 10000 estimating workload which takes just one milisecond end estimation 1 26975 100 0 26977 100 real 0m27.077s user 0m27.068s sys 0m0.003s
可以看到,这次的运行时间和执行时间也几乎相等.
去除预处理的时间后,运行时间和执行时间几乎是上一次的两倍
如下图
-
逻辑CPU数量=2,进程数量=1
(base) [root@ecs0003 linux_pro]# time taskset -c 0,1 ./sched 1 10000 10000 estimating workload which takes just one milisecond end estimation 0 13168 100 real 0m13.269s user 0m13.262s sys 0m0.000s
这与单个逻辑CPU时的数据几乎一模一样.计算存在两个逻辑cpu,其中一个也会闲着.果然是1核干活其他看.
-
逻辑CPU数量=2,进程数量=4
(base) [root@ecs0003 linux_pro]# time taskset -c 0,1 ./sched 4 10000 10000 estimating workload which takes just one milisecond end estimation 1 26318 100 0 26325 100 3 26417 100 2 26419 100 real 0m26.519s user 0m52.917s sys 0m0.004s
虽然运行时间与
逻辑CPU=1,进程=2
相似,但是执行时间几乎是它的两倍,这是因为两个进程可以同时在两核心上同一时间运行.
- 如果没有调度器的相关知识,我们很难理解为什么执行时间比运行时间长.但是通过上图我们就看出多核心对于吞吐量的意义,对于提升性能的意义了.
3.13 睡眠时的进程
进程一开始就进入睡眠会发生什么呢?
(base) [root@ecs0003 linux_pro]# time sleep 10
real 0m10.006s
user 0m0.000s
sys 0m0.002s
执行时间几乎为0,运行时间是10秒.
这意味这基本没有使用逻辑CPU.
3.14 现实中的进程
在现实的服务器中,进程会发生包括睡眠态在内的各种复杂的状态转换.
ps -eo
命令的etime
字段和time
字段分别表示进程从开始到执行命令为止的运行时间和执行时间
(base) [root@ecs0003 linux_pro]# ps -eo pid,comm,time,etime
PID COMMAND TIME ELAPSED
1 systemd 04:33:28 441-23:50:58
2 kthreadd 00:01:39 441-23:50:58
3 ksoftirqd/0 00:01:39 441-23:50:58
5 kworker/0:0H 00:00:00 441-23:50:58
7 migration/0 00:01:08 441-23:50:58
8 rcu_bh 00:00:00 441-23:50:58
9 rcu_sched 07:51:29 441-23:50:58
...........................................................................
172699 postmaster 00:07:06 15-00:25:08
178898 postmaster 00:00:00 7-01:40:49
180107 postmaster 00:00:06 1-00:05:19
180113 postmaster 00:00:03 1-00:05:19
180180 postmaster 00:00:00 1-00:05:05
182919 kworker/12:1 00:00:00 10:56:49
192684 kworker/7:1 00:00:00 10:26:49
195369 dio/dm-0 00:00:00 380-17:40:56
195831 kworker/9:0 00:00:21 2-00:06:03
200870 kworker/13:0 00:00:18 8-00:32:03
235215 kworker/10:2 00:00:00 09:26:46
254034 postmaster 00:03:42 4-22:08:51
254474 kworker/0:0 00:00:00 08:26:49
3.15 变更优先级
前面我们知道的,进程是通过轮询这样的算法进行平均分配逻辑CPU计算资源.
为特定进程指定优先级是可以的,nice()
命令可以达到此目的.
-
nice 可以通过-19到20指定进程的运行优先级,默认为0.其中,-19的优先级最高,20的优先级最低.
-
优先级高的进程可以比优先级低的进程获得更多的CPU时间.
-
只有root权限的用户才能进行提高优先级的操作,其他用户只能进行进程优先级的降低.
-
优先级除了在程序中调用函数来设定,比如c语言中的
nice(5)
.还可以通过执行nice命令通过-n选项直接设定.nice -n 5 echo hello
-
在
sar
命令中的%nice
字段的值,表示从默认值0更改为其他优先级后,进程所占用的时间比例.
下面我们降低loop.py
的运行优先级,观察sar的输出
(base) [root@ecs0003 linux_pro]# nice -n 5 python ./loop.py &
[1] 166863
(base) [root@ecs0003 linux_pro]# sar -P ALL 1 1
Linux 3.10.0-862.el7.x86_64 (ecs0003.novalocal) 07/25/2023 _x86_64_ (16 CPU)
11:23:10 AM CPU %user %nice %system %iowait %steal %idle
11:23:11 AM all 6.32 6.26 0.50 2.19 0.00 84.72
11:23:11 AM 0 0.00 0.00 0.00 0.00 0.00 100.00
11:23:11 AM 1 39.80 0.00 3.06 17.35 0.00 39.80
11:23:11 AM 2 0.00 0.00 0.00 0.00 0.00 100.00
11:23:11 AM 3 0.00 100.00 0.00 0.00 0.00 0.00
11:23:11 AM 4 11.88 0.00 1.98 5.94 0.00 80.20
11:23:11 AM 5 0.00 0.00 1.00 0.00 0.00 99.00
11:23:11 AM 6 0.00 0.00 0.00 0.00 0.00 100.00
11:23:11 AM 7 0.00 0.00 0.00 0.00 0.00 100.00
11:23:11 AM 8 29.00 0.00 1.00 8.00 0.00 62.00
11:23:11 AM 9 0.00 0.00 0.00 0.00 0.00 100.00
11:23:11 AM 10 0.00 0.00 0.00 0.00 0.00 100.00
11:23:11 AM 11 0.00 0.00 0.00 0.00 0.00 100.00
11:23:11 AM 12 0.00 0.00 0.00 0.00 0.00 100.00
11:23:11 AM 13 0.00 0.00 0.00 0.00 0.00 100.00
11:23:11 AM 14 0.00 0.00 0.00 0.00 0.00 100.00
11:23:11 AM 15 19.80 0.00 0.99 4.95 0.00 74.26
........................................................................................
Average: 13 0.00 0.00 0.00 0.00 0.00 100.00
Average: 14 0.00 0.00 0.00 0.00 0.00 100.00
Average: 15 19.80 0.00 0.99 4.95 0.00 74.26
(base) [root@ecs0003 linux_pro]# kill 166863
[1]+ Terminated nice -n 5 python ./loop.py
在不使用nice
命令后,%user字段由之前的100%变化为非100%,而%nice则出现了100%