IBM的LPI复习资料之LPI101-Topic103 :GNU和Unix命令(6)改变进程优先级

来源:互联网 发布:linux 解压缩zip 编辑:程序博客网 时间:2024/05/29 02:17

摘要:通过设置和改变进程的优先级来让进程获得所需要的运行时间片段。

1 概述

本文讲帮你在如下几个方面打牢基础:

  • (1) 理解进程优先级
  • (2) 设置进程优先级
  • (3) 改变进程优先级

本文为备考LPIC-1的目标103.6,权重为2。

2 理解你的优先级

与其他大多数现代操作系统一样,Linux也能运行多个进程。这通过进程间共享CPU和其他资源完成。如果一个进程占用了100%的CPU,那么其他进程将会失去反应。

如果你运行top命令,默认情况下,会按照CPU占用率降序显示各个进程。前面的例子中,我们展示了一个Poor Man's Colck脚本,它每30秒打印一次当前时间,其它时间内则没有动作。top可能不会把这个进程显示出来,因为它大部分时间都没有使用CPU。

典型的top输出:

Mem:   3924872k total,  3429320k used,   495552k free,   529468k buffersSwap:  7574520k total,        0k used,  7574520k free,  1872160k cached  PID USER      PR  NI  VIRT  RES  SHR S %CPU %MEM    TIME+  COMMAND 1580 mysql     20   0  870m  73m 6748 S  0.3  1.9 100:09.57 mysqld14163 root      20   0 15024 1384 1008 R  0.3  0.0   0:00.06 top    1 root      20   0 19228 1532 1248 S  0.0  0.0   0:11.62 init    2 root      20   0     0    0    0 S  0.0  0.0   0:00.00 kthreadd    3 root      RT   0     0    0    0 S  0.0  0.0   0:08.19 migration/0    4 root      20   0     0    0    0 S  0.0  0.0   0:10.33 ksoftirqd/0    5 root      RT   0     0    0    0 S  0.0  0.0   0:00.00 migration/0    6 root      RT   0     0    0    0 S  0.0  0.0   0:18.44 watchdog/0    7 root      RT   0     0    0    0 S  0.0  0.0   0:08.87 migration/1    8 root      RT   0     0    0    0 S  0.0  0.0   0:00.00 migration/1    9 root      20   0     0    0    0 S  0.0  0.0   0:14.39 ksoftirqd/1   10 root      RT   0     0    0    0 S  0.0  0.0   0:18.44 watchdog/1   11 root      RT   0     0    0    0 S  0.0  0.0   0:07.99 migration/2   12 root      RT   0     0    0    0 S  0.0  0.0   0:00.00 migration/2   13 root      20   0     0    0    0 S  0.0  0.0   0:14.89 ksoftirqd/2   14 root      RT   0     0    0    0 S  0.0  0.0   0:17.60 watchdog/2   15 root      RT   0     0    0    0 S  0.0  0.0   0:06.82 migration/3   16 root      RT   0     0    0    0 S  0.0  0.0   0:00.00 migration/3   17 root      20   0     0    0    0 S  0.0  0.0   0:05.61 ksoftirqd/3   18 root      RT   0     0    0    0 S  0.0  0.0   0:17.79 watchdog/3   19 root      20   0     0    0    0 S  0.0  0.0   6:35.02 events/0   20 root      20   0     0    0    0 S  0.0  0.0   6:39.81 events/1   21 root      20   0     0    0    0 S  0.0  0.0  70:32.21 events/2   22 root      20   0     0    0    0 S  0.0  0.0   8:35.72 events/3   23 root      20   0     0    0    0 S  0.0  0.0   0:00.00 cgroup   24 root      20   0     0    0    0 S  0.0  0.0   0:00.00 khelper   25 root      20   0     0    0    0 S  0.0  0.0   0:00.00 netns   26 root      20   0     0    0    0 S  0.0  0.0   0:00.00 async/mgr   27 root      20   0     0    0    0 S  0.0  0.0   0:00.00 pm   28 root      20   0     0    0    0 S  0.0  0.0   0:45.88 sync_supers   29 root      20   0     0    0    0 S  0.0  0.0   0:53.20 bdi-default   30 root      20   0     0    0    0 S  0.0  0.0   0:00.00 kintegrityd/0   31 root      20   0     0    0    0 S  0.0  0.0   0:00.00 kintegrityd/1

你的系统中可能会有一些进程使用很多的CPU资源,如视频编辑工具、图片格式转换工具或音频格式转换工具,如mp3转为ogg。

当你的机器上只有一个或者有限个数的CPU时,你需要决定如何在多个竞争进程之间共享CPU资源。这通常是通过选中一个进程让它运行一段时间(时间片),或者让它停止运行直到它等待的事件如IO完成。为了确保重要的进程不会因为CPU资源缺乏而失去反应,这种选择是基于调度优先级的。上表中的NI列代表的是进程的调度优先级,也叫做niceness。优先级通常是在-20到19之间,其中-20代表最高优先级,19代表最低优先级。

2.1 使用ps查看优先级

除了top命令外,也可以使用ps命令来显示进程优先级。使用ps -l,其输出的NI列就是进程优先级。如下所示:

[root@centos192 ~]# ps -lF S   UID   PID  PPID  C PRI  NI ADDR SZ WCHAN  TTY          TIME CMD4 S     0 14148 14146  0  80   0 - 27074 wait   pts/1    00:00:00 bash4 R     0 14548 14148  0  80   0 - 27030 -      pts/1    00:00:00 ps

2.2 默认优先级

你能已经从上面的两个例子中猜出来了,至少由普通用户启动的进程的优先级是0。这对现在的Linux系统来说是正确的。这个默认值可以通过运行不带参数的nice命令来获取。

ot@centos192 ~]# nice0

3 设置优先级

在我们学习如何设置和改变优先级之前,先构建一个CPU密集型的脚本,它将会展示优先级确实有影响。

3.1 一个CPU密集型的脚本

我们将创建一个只使用CPU的小脚本。这个脚本使用两个输入参数,一个是计数值,一个是标签。首先会打印出这个标签和当前的系统时间,然后进入循环,每次循环都使得计数值减一,当计数值为0时终止循环,打印出标签和时间。这个测试脚本中没有进行错误检测也不是非常健壮,但是它可以说明问题了。

[root@centos192 ~]# echo 'x="$1"' > count1.sh[root@centos192 ~]# echo 'echo "$2" $(date)' >> count1.sh[root@centos192 ~]# echo 'while [ $x -gt 0 ]; do x=$((x-1)); done' >>count1.sh[root@centos192 ~]# echo 'echo "$2" $(date)' >>count1.sh[root@centos192 ~]# cat count1.shx="$1"echo "$2" $(date)while [ $x -gt 0 ]; do x=$((x-1)); doneecho "$2" $(date)

如果你在电脑上运行这个脚本,可能的输出如下:

[root@centos192 ~]# ./count1.sh 10000 AA 2013年 08月 09日 星期五 10:30:28 CSTA 2013年 08月 09日 星期五 10:30:28 CST[root@centos192 ~]# ./count1.sh 99000 AA 2013年 08月 09日 星期五 10:30:43 CSTA 2013年 08月 09日 星期五 10:30:45 CST

目前位置一切安好。现在我们在后台运行这个脚本,然后使用top命令来查看其CPU占有情况。

Tasks: 188 total,   2 running, 186 sleeping,   0 stopped,   0 zombieCpu(s): 23.8%us,  1.2%sy,  0.0%ni, 74.8%id,  0.1%wa,  0.0%hi,  0.0%si,  0.0%stMem:   3924872k total,  3438424k used,   486448k free,   529588k buffersSwap:  7574520k total,        0k used,  7574520k free,  1873432k cached  PID USER      PR  NI  VIRT  RES  SHR S %CPU %MEM    TIME+  COMMAND29561 root      20   0  105m 1096  728 R 99.6  0.0   1:06.54 bash  695 root      20   0     0    0    0 S  0.3  0.0   4:35.89 vmmemctl29562 root      20   0 15024 1388 1008 R  0.3  0.0   0:00.13 top    1 root      20   0 19228 1532 1248 S  0.0  0.0   0:11.67 init    2 root      20   0     0    0    0 S  0.0  0.0   0:00.00 kthreadd

可以看出,我们的脚本使用了一个CPU的99.6的资源,如果想占用其他的CPU,则再运行上面的命令即可。如果脚本持续运行,那么将会严重影响系统的其他工作。

3.2 使用nice命令设置优先级

既然我们能够持续保持一个CPU处于繁忙状态,我们来看看如何设置一个进程的优先级。总结一下到目前为止我们学到的知识:

  • (1) Linux和Unix系统使用的优先级共有40个等级,从-20到+19.
  • (2) 普通用户启动的进程默认优先级是0.
  • (3) ps命令的-l选项可以显示进程的优先级
  • (4) nice命令来显示默认的优先级

nice除了可以显示默认优先级外,还可以用来按照指定的优先级启动一个进程。你可以使用-n(或者--adjustment)选项接一个正数来增加优先级值,接一个负数来减少优先级值。一定要记住优先级值越大,优先级越低。通常只有root用户才能指定负值,也就是说普通用户只能让进程优先级降低而不能提升。

为了演示使用nice设置优先级,我们使用相同的脚本启动两个进程,其中一个进程的优先级为19,另一个默认。一秒以后使用ps-l 来显示进程状态,包括优先级。最后我们增加了一个30秒的睡眠来保证在子sh运行完之后才退出命令。如下图所示:

[root@centos192 ~]# (sh count1.sh 2000000 A&);(nice -n 19 sh count1.sh 2000000B&);sleep 1; ps -l; sleep 30A 2013年 08月 09日 星期五 12:29:10 CSTB 2013年 08月 09日 星期五 12:29:10 CSTF S   UID   PID  PPID  C PRI  NI ADDR SZ WCHAN  TTY          TIME CMD4 S     0 29538 29536  0  80   0 - 27074 wait   pts/2    00:00:00 bash0 R     0 30573     1 99  80   0 - 26514 -      pts/2    00:00:01 sh0 R     0 30575     1 99  99  19 - 26514 -      pts/2    00:00:00 sh4 R     0 30579 29538  0  80   0 - 27030 -      pts/2    00:00:00 psB 2013年 08月 09日 星期五 12:29:39 CSTA 2013年 08月 09日 星期五 12:29:40 CST

可能你会感到奇怪,这两个子进程几乎同时运行完毕。我们设置的优先级没有作用吗?请记住我们的脚本只使用一个CPU。此次运行的机器配备的是4核心的CPU。这样两2个子进程分别运行在不同的CPU核心上,也许没有必要让谁优先了。为了占满4个CPU核心,我们这次同时运行6个进程,优先级分别是0,4,8,12,16,19。

[root@centos192 ~]# (sh count1.sh 5000000 A&);(nice -n 4 sh count1.sh 5000000B&);(nice -n 8 sh count1.sh 5000000 C&);(nice -n 12 sh count1.sh 5000000D&);(nice -n 16 sh count1.sh 5000000 E&);(nice -n 19 sh count1.sh 5000000F&);sleep 1; ps -l; sleep 30; A 2013年 08月 09日 星期五 12:25:05 CSTB 2013年 08月 09日 星期五 12:25:05 CSTC 2013年 08月 09日 星期五 12:25:05 CSTD 2013年 08月 09日 星期五 12:25:05 CSTE 2013年 08月 09日 星期五 12:25:05 CSTF 2013年 08月 09日 星期五 12:25:05 CSTF S   UID   PID  PPID  C PRI  NI ADDR SZ WCHAN  TTY          TIME CMD4 S     0 29538 29536  0  80   0 - 27074 wait   pts/2    00:00:00 bash0 R     0 30471     1 50  80   0 - 26514 -      pts/2    00:00:01 sh0 R     0 30473     1 50  84   4 - 26514 -      pts/2    00:00:01 sh0 R     0 30475     1 49  88   8 - 26514 -      pts/2    00:00:00 sh0 R     0 30477     1 30  92  12 - 26514 -      pts/2    00:00:00 sh0 R     0 30480     1 12  96  16 - 26514 -      pts/2    00:00:00 sh0 R     0 30484     1  6  99  19 - 26514 -      pts/2    00:00:00 sh4 R     0 30489 29538  0  80   0 - 27029 -      pts/2    00:00:00 psC 2013年 08月 09日 星期五 12:26:19 CSTA 2013年 08月 09日 星期五 12:26:19 CSTB 2013年 08月 09日 星期五 12:26:20 CSTD 2013年 08月 09日 星期五 12:26:49 CSTE 2013年 08月 09日 星期五 12:27:15 CSTF 2013年 08月 09日 星期五 12:27:25 CST

可以看出,如此一来就会出现多个进程使用竞争CPU的情况了,基本上优先级越高,那么被执行的机会就越多,执行完毕使用的时间就越少。

最后提醒大家,如同nohup命令一样,nice命令不能使用命令列表或者管线作为参数。

4 改变优先级

4.1 renice

如果你已经启动了一个进程,之后又意识到需要改变这个进程的优先级,那么就可以使用renice命令。renice指定的是绝对优先级值而不是调整量。

i[root@centos192 ~]# sh count1.sh 10000000 A&[1] 30799[root@centos192 ~]# A 2013年 08月 09日 星期五 12:43:19 CST[root@centos192 ~]# renice 1 30799; ps -l 3079930799: old priority 0, new priority 1F S   UID   PID  PPID  C PRI  NI ADDR SZ WCHAN  TTY        TIME CMD0 R     0 30799 29538 97  81   1 - 26514 -      pts/2      0:21 sh count1.sh10000000 A[root@centos192 ~]# renice +3 30799; ps -l 3079930799: old priority 1, new priority 3F S   UID   PID  PPID  C PRI  NI ADDR SZ WCHAN  TTY        TIME CMD0 R     0 30799 29538 98  83   3 - 26514 -      pts/2      0:40 sh count1.sh10000000 A

注意,只有root用户才能提高进程的调度优先级,让进程变得不太nice。更多信息参考nice和renice的man手册页。

原创粉丝点击