第十章 进程

前言

  1. 现代操作系统通常都支持多重任务管理。
  2. 多重任务处理是指系统通过快速切换运行中的程序来实现多个任务的同时执行。
  3. Linux 内核通过使用进程来管理多重任务。
  4. 进程是 Linux 用来安排不同程序等待 CPU 调度的一种组织方式。
  5. 有时候计算机运行速度会变得很慢,或者应用程序会停止响应。
  6. 本章将介绍命令行中可用来查看程序当前的运行情况以及终止运行异常的进程的一些工具:
  • ps: 实现当前所有进程的运行情况
  • top: 实时显示当前所有任务的资源占用情况
  • jobs: 列出所有活动作业的状态信息
  • bg: 设置在后台中运行作业
  • fg: 设置在前台中运行作业
  • kill: 杀死指定名字的进程
  • shutdown: 关机或者重启系统

进程如何工作

基本介绍

  1. 系统启动时,内核先把它的一些程序初始化为进程,然后运行一个称为 init 的程序。
  2. init 程序将依次运行一系列称为脚本初始化 (init script) 的 shell 脚本 (放在 /etc 目录下) ,这些脚本将会启动所有的系统服务。其中的很多服务都是通过守护程序 (daemon program) 来实现的。
  3. 后台程序只是呆在后台做它们自己的事情,并且没有用户界面。
  4. 因此,即使没有用户登录,系统也在忙于执行一些例行程序。
  5. 一个程序的运行可以触发其他程序的运行,在进程系统中这种情况被表述为父进程创建子进程。
  6. 内核会保存每个进程的信息以便确保任务有序进行。比如,每个进程将被分配一个称为进程 ID (PID , Process ID) 的号码。
  7. 进程 ID 是按递增的顺序来分配的, init 进程的 PID 始终为 1 。
  8. 内核也记录分配给每个进程的内存信息以及用来恢复运行的进程的就绪信息。
  9. 和文件系统类似,进程系统中也存在所有者、用户ID 、有效用户ID 等。

使用 ps 命令来查看进程信息

  1. ps 基本介绍
  • 用来查看进程信息的命令中 (有多个) ,使用最普遍的就是 ps 命令。
  • ps 命令有很多选项,其中最简单的使用格式如下:
    1
    2
    3
    4
    [me@linuxbox ~]$ ps
    PID TTY Time CMD
    5198 pts/1 00:00:00 bash
    10129 pts/1 00:00:00 ps
  • 这个例子的输出结果列出了两个进程:进程 5198 和进程 10129 ,它们分别对应 bash 命令和 ps 命令。
  • 我们可以发现,默认情况下, ps 命令输出的信息并不是很多,只是输出和当前终端会话相关的进程信息。
  • 为了获取更多的信息,我们需要添加一些选项,但是在介绍这个之前,让我们先看看 ps 命令输出的其他字段信息。
  • TTY 是 teletype (电传打字机) 的缩写,代表了进程的控制终端 (controlling terminal) 。
  • UNIX 在这里也显示了进程的运行时间, TIME 字段表示了进程消耗的 CPU 时间总和。
  • 如果在 ps 命令后面添加一个选项,那么我们将得到反映系统运行情况的更大的视图界面。
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    [me@linuxbox ~]$ ps x
    PID TTY STAT TIME COMMAND
    2799 ? Ss1 0:00 /usr/libexec/bonbb-activation-server -ac
    2820 ? S1 0:01 /usr/libexec/evolution-data=server-1.10 --
    15647 ? Ss 0:00 /bin/sh /usr/bin/statkde
    15751 ? Ss 0:00 /usr/bin-ssh-agent /usr/bin/dbus-lauch --
    15754 ? S 0:00 /usr/bin/dbus-lauch --exit -with-session
    15755 ? Ss 0:01 /bin/dbus-daemon --fork --print-pid 4 -pr
    15774 ? Ss 0:02 /usr/bin/gpg-agent -s -daemon
    15793 ? S 0:00 start_kdeinit --new-starup + kcminit_start
    15794 ? Ss 0:00 kdeinit Runing...
    15797 ? S 0:00 dcopserver -nosid

    and many more...
  • 添加 x 选项 (注意这里没有前置的连字符的连字符) 将告知 ps 命令显示所有的进程,而不需要关注它们是由哪个终端所控制。
  • TTY 列中出现的 ? 表示没有控制终端,使用这个选项可以查看所有进程的列表信息。
  • 把 ps 命令的输出作为 less 命令输入的方法通常很管用,它可以更方便地查看显示结果。
  1. 进程状态
状态 含义
R 运行状态。进程正在运行或者准备运行
S 睡眠状态。进程不在运行,而是等待某时间发生,如果键盘输入或者收到网络报文。
D 不可中断的睡眠状态。进程正在等待 I/O 操作,如应判断动
T 暂停状态。进程被指示
Z 无效或者僵尸进程。子进程被终止,但是还没有被其父进程彻底释放掉
< 高优先级进程。进程可以被赋予更多的重要性,分配更多的 CPU 时间。进程的这一特性成为优先级 (niceiness) 。高优先级的进程被说成较不友好,是因为它将消耗更多的 CPU 时间,这样留给其他进程的 CPU 时间就会变少
N 低优先级。低优先级 (a nice process) 只有在其他更高优先级的进程使用完处理器后才能够获得试用处理器的时间
  1. ps aux 指令
  • ps 另一个常用的选项组合是 aux (不带前置连字符) ,它将输出更多的信息,如下所示。
    1
    2
    3
    4
    5
    6
    7
    8
    9
    [me@linuxbox ~]$ ps aux
    USER PID %CPU %MEM VSZ RSS TYY STAT START TIME COMMAND
    root 1 0.0 0.0 2136 644 ? Ss Mar05 0:31 init
    root 2 0.0 0.0 0 0 ? S< Mar05 0:00 [kt]
    root 3 0.0 0.0 0 0 ? S< Mar05 0:00 [mi]
    root 4 0.0 0.0 0 0 ? S< Mar05 0:06 [ks]
    root 5 0.0 0.0 0 0 ? S< Mar05 0:36 [wa]
    root 6 0.0 0.0 0 0 ? S< Mar05 0:00 [ev]
    root 7 0.0 0.0 0 0 ? S< Mar05 0:00 [kh]
  • 该选项组合将会显示属于每个用户的进程信息,使用这些选项时不带前置连字符将使得命令以 BSD 模式 (BSD-style) 运行。
  1. BSD 模式下 ps 命令输出的列标题
标题 含义
USER 用户 ID:表示该进程的所有者
%CPU CPU 使用百分比
%MEM 内存使用百分比
VSZ 虚拟耗用内存大小
RSS 实际使用的内存大小,进程使用的物理内存 (RAM) 大小 (以 KB 为单位)
START 进程开启的时间,如果数值超过 24 小时,那么将使用日期来表示

使用 top 命令动态查看进程信息

  1. top 基本介绍
  • 虽然 ps 命令可以显示有关机器运行情况的很多信息,但是它提供的只是在 ps 被执行时刻机器状态的一个快照。
  • 要查看机器运行情况的动态视图,我们可以使用 top 命令,如下所示:
    1
    [me@linuxbox ~]$ top
  • top 程序将按照进程活动的顺序,以列表的形式持续更新系统进程的当前信息 (默认每 3 秒更新一次) 。
  • top 主要用于查看系统最高 (top) 进程的运行情况,其名字也来源于此。
  • top 命令显示的内容包含两个部分,顶部显示的是系统总体状态信息,下面显示的是一张按 CPU 活动时间排序的进程情况表。
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    top-14:59:20 up 6:30, 2users, load average: 0.07, 0.02, 0.00
    Tasks: 109 total, 1 running, 106 sleeping, 0 stopped, 2 zombie
    Cpu(s): 0.7%us, 1.0%sy, 0.0%ni, 98.3%id, 0.0%wa, 0.0%hi, 0.0%si
    Mem: 319496k total, 314860k used, 4636k free, 19392k buff
    Swap: 875500k total, 149128k used, 726372k free, 114676k cach

    PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
    6244 me 39 19 31752 3124 2188 S 6.3 1.0 16:24.42 trackerd
    11071 me 20 0 2304 1092 840 R 1.3 0.3 0:00.14 top
    6180 me 20 0 2700 1100 772 S 0.7 0.3 0:03.66 dbus-dae
    6321 me 20 0 20944 7248 6560 S 0.7 2.3 2:51.38 multiloa
    4955 root 20 0 104m 9668 5776 S 0.3 3.0 2:19.39 Xorg
    1 root 20 0 2976 528 476 S 0.0 0.2 0:03.14 init
    ...
  1. top 细节说明
字段 含义
1 top 程序名
14:59:20 一天中的当前时间
up 6:30 正常运行时间 (uptime) 。从机器最后一次启动开始计算的时间总数。在这个例子中,系统已经运行了 6.5 小时。
2 users 有两个用户已登录
load average 负载均衡 (load average) 指的是等待运行的进程数;即共享 CPU 资源的处于可运行状态的进程数。显示的三个值分别对应不同的时间段:第一个对应的是前 60 秒的均值,下一个对应的是前 5 分钟的均值,最后一个对应的是前 15 分钟的均值。该值小于 1.0 表示该机器并不忙
2 task 统计进程数及各个进程的状态信息
0.7%us 0.7% 的 CPU 时间被用户进程占用,这里指的是处于内核外的进程
1.0%sy 1.0% 的 CPU 时间被系统进程 (内核进程) 占用
0.0%ni 0.0% 的 CPU 时间被友好进程 (低优先级进程) 占用
98.3%id 98.3% 的 cpu 时间是空闲的
0.0%wa 0.0% 的 CPU 时间用来等待 I/O 操作
Mem 显示物理 RAM 的使用情况
Swap 显示交换空间 (虚拟内存) 的使用情况
  1. top 补充说明
  • top 程序可以接受许多键盘指令,其中最常用的有两个:一个是 h ,输入后将显示程序的帮助界面;另一个是 q ,用来退出 top 命令。

控制进程

基本介绍

  1. xlogo 程序是由 X 窗口系统 (X Window System ,使得显示器支持图形化界面的底层引擎) ,提供的一个示例程序,他只是简单地显示一个包含 X 标识的可缩放窗口。
  2. 首先,我们认识一下实验对象。
    1
    [me@linuxbox ~]$ xlogo
  3. 输入该命令后,包含该标识的一个小窗口将在屏幕的某个地方出现。有些系统中, xlogo 可能会输出一条告警信息,但是我们可以忽略它,因为它并不会造成什么影响。
  4. 如果系统中不包含 xlogo 程序,那么试着使用 gedit 程序或者 kwrite 程序来替代。
  5. 我们可以通过改变窗口的大小来验证 xlogo 是否处于运行状态。
  6. 如果该表示适应新的窗口大小被重新绘制了,则表明该程序正在运行。
  7. 如果关闭 xlogo 窗口,那么提示符将返回。

中断进程

  1. 首先,输入 xlogo 命令,并确保程序在正常运行。接下来,返回到终端窗口,按下 Ctrl-C 键。
    1
    2
    [me@linuxbox ~]$ xlogo
    [me@linuxbox ~]$
  2. 在终端里按下 Ctrl-C 键会中断 (interrupt) 一个程序,它意味着我们委婉地请求程序结束。按下 Ctrl-C 键后, xlogo 窗口将关闭, shell 提示符将返回。

使进程在后台运行

  1. 假设我们想要 shell 提示符返回,但又不终止 xlogo 程序,那么可以通过让该程序在后台 (background) 运行来实现。
  2. 我们可以把终端想象为有一个前台 (foreground) 和一个后台。
  3. 要想在启动程序时让该程序在后台运行,可以在命令后面加上和号字符 & 来实现。
    1
    2
    3
    [me@linuxbox ~]$ xlogo &
    [1] 28236
    [me@linuxbox ~]$
  4. 命令执行后,将出现 xlogo 窗口,而且 shell 提示符也可以返回,但是同时也会打印一些有趣的数字信息。
  5. 这条信息是 shell 的一个称为作业控制 (job control) 的特性表现。
  6. shell 通过这条这条信息来显示已经启动的作业编号为 1([1]) , 其对应的 PID 是 28236 。
  7. 如果执行 PS 命令,可以查看到当前运行的进程。
    1
    2
    3
    4
    5
    [me@linuxbox ~]$ PS
    PID TTY TIME CMD
    10603 pts/1 0:00:00 bash
    28236 pts/1 0:00:00 xlogo
    28239 pts/1 0:00:00 ps
  8. shell 的作业控制特性也提供了一种方式来查看从该终端启动的所有作业。
  9. 使用 jobs 命令可以得到如下信息:
    1
    2
    [me@linuxbox ~]$ jobs
    [1]+Running xlogo &
  10. 输出结果现实存在一个编号为 1 的作业在运行,而且对应命令是 xlogo & 。

使进程回到前台运行

  1. 后台运行的进程不会收到任何键盘输入的影响,包括试图用来中断它的 Ctrl-C 键。要想是的进程返回到前台来运行,可以使用 fg 命令来实现,参见下面的例子。
    1
    2
    3
    4
    [me@linuxbox ~]$ jobs
    [1]+Running xlogo &
    [me@linuxbox ~]$ fg %1
    xlogo
  2. 我们可以通过在 fg 后面加上百分比符号和作业编号 (称为 jobspec 选项) 来实现这个功能。如果后台只有一个任务,那么可以不带 jobspec 选项,这时候按下 Ctrl-C 键就可以终止 xlogo 命令。

暂停进程

  1. 如果我们只是想要暂停进程,而不是终止进程,那么通常需要我们将前台运行的进程移到后台去运行。
  2. 我们为了暂停前提进程需要按下 Ctrl-Z 键,让我们试试如下操作,在命令提示符后输入 xlogo ,按下 Enter 键后再按下 Ctrl-Z 键。
    1
    2
    [me@linuxboy ~]$ xlogo
    [1] + Stopped xlogo
  3. 在暂停 xlogo 命令后,我们可以试图改变 xlogo 图口的大小来确认该程序是否被暂停了。
  4. 我们可以使用 fg 命令让进程在前台恢复运行,也可以使用 bg 命令让进程移到后台运行:
    1
    2
    3
    [me@linuxboy ~]$ bg %1
    [1]+xlogo %
    [me@linuxboy ~]$
  5. 在使用 fg 命令,如果只存在一个作业,那么可以不带 jobspec 选项。
  6. 如果用命令方式启动了一个图形化程序,但是忘了在命令尾部加上 & 符号来让程序在后台进行,那么在这种情况下,把进程从前台移到后台去运行的方法将非常方便。

信号

基本介绍

  1. kill 命令通常用来杀死进程,它可以用来终止运行不正常的程序或者反过来拒绝终止的程序。
    1
    2
    3
    4
    [me@linuxboy ~]$ xlogo &
    [1] 28401
    [me@linuxboy ~]$ kill 28401
    [1]+Terminated xlogo
  2. 我们首先在后台启动了 xlogo 程序, shell 将打印输出改后台进程的 jobspec 选项信息和 PID 信息。接着,我们使用了 kill 命令,并且指定想要终结进程的 PID 。我们也可以使用 jobspec 选项代替 PID 信息来指定该进程。
  3. 信号是操作系统和程序间通信的多种方式之一,在使用 Ctrl-C 键和 Ctrl-Z 键时已经见识过信号的作用。当终端接收到其中的一个输入时,它将发送信号到前台进程。
  4. 在按下 Ctrl-C 键的情况下,它发送一个称为 INT (中断,Interrupt) 的信号;在按下 Ctrl-Z 的情况下,它将发送一个称为 TSTP (中断暂停,Terminal Stop) 的信号。

使用 kill 命令发送信号到进程

  1. kill 基本介绍
  • kill 命令最常用的语法格式如下:
    1
    kill [-signal] PID...
  • 如果命令行中没有指定信号,那么默认发送 TERM (Terminate) 信号。
  1. kill 常用信号
信号编号 信号名 含义
1 HUP 挂起信号。该信号用来指示程序控制终端已被挂起。该信号的效果通过关闭终端会话的方式来表现,运行在终端上的前台程序收到该信号后将终止。该信号也被很多后台程序用来进行重新初始化。这意味着,当一个后台进程接收到该信号时,它将重启并且重新读取它的配置文件。 Apache Web 服务器就是后台进程使用 HUP 信号重新初始化的一个例子
2 INT 中断信号。执行效果何在终端按下 Ctrl-C 键的效果一样。通常用来终止一个程序
9 KILL 杀死信号。该信号比较特殊。鉴于程序可以选择不同的方式来处理发送过来的信号,包括忽略所有的这些信号,KILL 信号将不会真正意义上地被发送到目标程序。而是内核宁愿立即终止了该进程。当进程以这种方式被终止时,压根没有机会对它自己进行清理或者对当前工作进行保存。考虑到这个原因,KILL 信号只能当作其他的终端信号都执行失败的情况下的最后选择。
15 TREM 终止信号。这是 kill 命令默认发送的信号类型。如果程序仍然有足够的活力 (alive enough) 来接收信号,那么它将被终止
18 CONT 继续运行信号。恢复之前即接受了 STOP 信号的进程
19 STOP 暂停信号。该信号将使进程暂停,而不是终止。和 KILL 信号类似,该信号不会被发送给目标进程,因此它不能被忽略
  1. kill 案例
  • 按照下面的方式使用 kill 命令。
    1
    2
    3
    4
    [me@linuxboy ~]$ xlogo &
    [1] 13546
    [me@linuxboy ~]$ kill -1 13546
    [1]+Hangup xlogo
  • 在这个例子中,我们首先在后台启动了 xlogo 程序,接着使用 kill 命令给它发送 HUP 信号。
  • xlogo 程序将终止, shell 的输出信息表明了这个后台进程已经接收了一个挂起信号。你也许需要多敲几次 Enter 键才能看到这条输出信息。
  • 注意,你可以通过信号编号指定信号,其中包含带有 SIG 前缀的信号名。
    1
    2
    3
    4
    5
    6
    7
    8
    [me@linuxbox ~]$ xlogo &
    [1] 13601
    [me@linuxbox ~]$ kill -INT 13601
    [1]+Interrupt xlogo
    [me@linuxbox ~]$ xlogo &
    [1] 13608
    [me@linuxbox ~]$ kill -SIGINT 13608
    [1]+Interrupt xlogo
  • 和文件一样,进程也有所有者,只有进程的所有者 (或者超级用户) 才能使用 kill 命令来给它发送信号。
  1. kill 其他常用信号
信号编号 信号名 含义
3 QUIT 退出信息
11 SEGV 段错误信号。如果程序非法使用了内存空间,即程序试图在没有写权限的空间执行写操作,那么系统将发送该信号。
20 TSTP 终端暂停信号。在按下 Ctrl-Z 键时终端将发出该信号。与 STOP 信号不同的是, TSTP 信号由程序接收,但是程序可以选择忽略该信号。
28 WHNCH 窗口改变信号。当窗口改变大小的时,系统将发送该信号。类似 top 和 less 的一些程序将会对该信号作出响应,重新绘制视图来适应新的窗口大小。
  1. kill 补充说明
  • 如果想要查看更多的信号,使用如下命令将显示完整的信号列表。
    1
    [me@linuxbox ~]$ kill -l

使用 killall 命令发送信号给多个进程

  1. killall 基本介绍
  • 通过使用 killall 命令,我们可以给指定程序或者指定用户名的多个进程发送信号。一般语法格式如下:
    1
    killall [-u user] [-signal] name...
  • 要证明这一点,我们可以先启动两个 xlogo 程序实例,然后终止它们。
    1
    2
    3
    4
    5
    6
    7
    [me@linuxbox ~]$ xlogo &
    [1] 18801
    [me@linuxbox ~]$ xlogo &
    [2] 18802
    [me@linuxbox ~]$ killall xlogo
    [1]-Terminated xlogo
    [2]-Terminated xlogo

更多与进程相关的命令

命令 描述
vmstat 输出系统资源使用情况的快照,包括内存,交换空间和磁盘 I/O 。如果想要持续查看输出,可以在命令后面加上一个间隔时间 (以秒为单位) ,命令将按照间隔时间来动态更新显示的内容。按下 Ctrl-C 键可以终止输出。
tload 类似于 xload 程序,但是图形是在终端上绘制。按下 Ctrl-C 键终止输出。

参考文章

  • 转载:Linux 命令行大全