学习 Linux,101: 创建、监控和终止进程_VMware, Unix及操作系统讨论区_Weblogic技术|Tuxedo技术|中间件技术|Oracle论坛|JAVA论坛|Linux/Unix技术|hadoop论坛_联动北方技术论坛  
网站首页 | 关于我们 | 服务中心 | 经验交流 | 公司荣誉 | 成功案例 | 合作伙伴 | 联系我们 |
联动北方-国内领先的云技术服务提供商
»  游客             当前位置:  论坛首页 »  自由讨论区 »  VMware, Unix及操作系统讨论区 »
总帖数
1
每页帖数
101/1页1
返回列表
0
发起投票  发起投票 发新帖子
查看: 4327 | 回复: 0   主题: 学习 Linux,101: 创建、监控和终止进程        下一篇 
cc
注册用户
等级:中校
经验:1900
发帖:195
精华:0
注册:2011-7-25
状态:离线
发送短消息息给cc 加好友    发送短消息息给cc 发消息
发表于: IP:您无权察看 2011-8-8 12:49:36 | [全部帖] [楼主帖] 楼主

概述

本文深入介绍基础的 Linux 进程管理技术。您将学习如何:

  • 管理前台和后台作业
  • 启动在注销之后仍将运行的进程
  • 监控进程
  • 根据需要选择和排列进程的显示方式
  • 向进程发送信号

本文帮助您准备 Linux Professional Institute's Junior Level Administration (LPIC-1) 考试的 103 主题下的 103.5 考核目标。该考核目标的权值为 4。

先决条件

为了从本文获得最大的收益,您应该具备基础的 Linux 知识,并且具有一个能够正常运行的 Linux 系统,您将在 Linux 系统上练习本文讨论的命令。不同版本的程序输出的结果的格式可能不同,因此您的结果可能与本文图片和清单所示的结果有所不同。本文的例子显示的结果来自于 Ubuntu 9.10 (Karmic Koala) 发行版。



管理前台和后台作业

联系 Ian


Ian 是我们最受欢迎并且很多产的作者之一。查看
Ian 的个人资料 并与他和 My developerWorks 上的其他作者和读者联系。

您只要停下来仔细思考一下就会发现,除了本系列早期文章讨论的终端程序之外,您的电脑还运行着许多其他程序。事实上,如果您使用图形化桌面,您可能一次打开了多个终端窗口,或者打开了文件浏览器、Internet 浏览器、游戏、电子表格或其他应用程序。我们以前介绍的例子已经演示了在一个终端窗口中输入的命令。您要等待该命令运行完毕之后才能运行其他命令。在本文中,您将了解如何通过终端窗口一次运行多个命令。

当您在终端窗口运行命令时,您是在前台

运行它。大部这些命令的运行都很快,但现在假设您运行的是图形化桌面,并且想在桌面上显示一个数字时钟。尽管大部分图形化桌面都有一个时钟,我们仍然以此作为例子。

如果您安装了 X Window System,您也许会拥有一些实用程序,比如 xclock 或 xeyes。如果您还没有安装这些实用程序,您可以在名为 xorg-x11-apps 或 x11-apps 的包中找到它们。这两个包中的实用程序都可以在本例中使用,但我们选择使用 xclock。根据实用程序的手册页,您可以通过以下命令在图形化桌面上启动数字时钟:

xclock -d -update 1


-update 1 部分请求每秒钟更新一次;如果取消该选项,时钟将每分钟更新一次。让我们在终端窗口中运行该命令。您将看到一个类似于图 1 的时钟,您的终端窗口类似于清单 1。如果您没有 xclock 或 X Window System,稍后您将看到如何在终端窗口中创建一个简易的数字时钟。现在,您先根据本文的步骤学习,并以该时钟作为例子进行练习。

注意:在撰写本文时,有一个 bug 在启用桌面效果时会影响 xclock。最明显的影响是标题栏不变化,即使操作它时也是这样。如果您的 xclock 例子与本文的不同,您可能要关闭桌面效果一段时间。

图 1. 带有 xclock 字样的数字时钟
北京联动北方科技有限公司

清单 1. 启动 xclock


ian@attic4:~$ xclock -d -update 1


不幸的是,您的终端窗口不再出现命令提示符,因此您要恢复它。幸好 Bash shell 有一个暂停

键 Ctrl-z。按下该组合键将恢复终端提示符,如清单 2 所示。

清单 2. 使用组合键 Ctrl-z 暂停 xclock


ian@attic4:~$ xclock -d -update 1
^Z
[1]+ Stopped xclock -d -update 1


xclock 数字时钟仍然出现在桌面上,但它已经停止运行。事实上,如果您拖动另一个窗口让它与时钟的一部分重叠,时钟被重叠的部分仍然会保持不变。注意,终端输出消息显示 “[1]+  Stopped”。该消息中的 1 表是作业编号

。您可以通过输入 fg %1 重新启动时钟。您还可以通过输入 fg %xclock 或 fg %?clo 使用命令名或命令名的一部分。最后,您仅需要输入不带任何参数的 fg 就可以重新启动最近停止的作业,如本例中的 job 1。使用命令 fg 重启任务还会将其带回到前台,因此不再出现 shell 提示符。您需要做的就是将作业放回到

后台

;bg 命令的作业指示与 fg 命令相同,它的作用就是将作业放回到后台。

清单 3 显示如何将 xclock 作业带回到前台,并使用两种形式的 fg 命令暂停它。您可以再次暂停它并将它放到后台;此时,即使您在终端窗口运行其他程序,时钟仍会继续运行。

清单 3. 将 xclock 放在前台或后台


ian@attic4:~$ fg %1
xclock -d -update 1
^Z
[1]+ Stopped xclock -d -update 1
ian@attic4:~$ fg %?clo
xclock -d -update 1
^Z
[1]+ Stopped xclock -d -update 1
ian@attic4:~$ bg
[1]+ xclock -d -update 1 &


使用 “&”

您可能已经注意到,当您将 xclock 放在后台时,该消息不再显示 “Stopped”,并且使用与符号 (&) 终止了它。事实上,您根本不需要暂停程序就可以将它放到后台;您仅需将一个与符号 (&) 添加到该命令的后面 shell 就会在后台启动该命令(或命令列表)。让我们通过该方法启动一个背景为白色的带指针时钟。您将看到类似于图 2 所示的时钟,其终端输出类似于清单 4。

图 2. 带有 xclock 字样的指针式时钟
北京联动北方科技有限公司

清单 4. 使用 & 在后台启动指针式时钟


ian@attic4:~$ xclock -bg wheat -update 1&
[2] 4320


注意,这次显示的消息与上一次略有不同。它显示一个作业编号和一个进程 ID(PID)。我们稍后将更详细地讨论 PID 和状态。目前我们使用 jobs 命令找出有多少个作业正在运行。添加 -l 选项来列出 PID,您将看到 job 2 的 PID 为 4320,如清单 5 所示。此外还要注意,job 2 的作业编号旁边有一个加号 (+),这表明它是现正在运行

的作业。如果 fg 命令不带有任何作业指示,该作业将出现在前台。

清单 5. 显示作业和进程信息


ian@attic4:~$ jobs -l
[1]- 3878 Running xclock -d -update 1 &
[2]+ 4320 Running xclock -bg wheat -update 1 &


在解决其他与后台作业相关的问题之前,我们先看看一个自制的简易数字时钟。我们使用 sleep 命令将显示推迟两秒,然后使用 date 命令打印当前的日期和时间。我们将这两个命令放在一个 while 循环中,该循环带有一个用于创建无限循环的 do/done 代码块。最后,我们将所有代码放在一对圆括号中构成一个命令列表,然后使用与号将整个列表放到后台。本系列后面的文章介绍如何使用循环和脚本构建更加复杂的命令。清单 6. 简易的数字时钟


ian@attic4:~$ (while sleep 2; do date;done)&
[2] 4856
ian@attic4:~$ Tue Jan 19 09:23:30 EST 2010
Tue Jan 19 09:23:32 EST 2010
Tue Jan 19 09:23:34 EST 2010
fTue Jan 19 09:23:36 EST 2010
Tue Jan 19 09:23:38 EST 2010
gTue Jan 19 09:23:40 EST 2010

( while sleep 2; do
date;
done )
Tue Jan 19 09:23:42 EST 2010
Tue Jan 19 09:23:44 EST 2010
Tue Jan 19 09:23:46 EST 2010
^C



我们创建的命令列表作为 job 2 运行,其 PID 为 4856。每隔两秒钟将运行 date 命令,并且将日期和时间打印在终端窗口上。您输入的内容将突出显示。如果您的输入速度很慢,在输入完整的命令之前,您输入的字符就被几行输出隔开了。事实上,您为了将命令列表放到前台而输入的 “f” 和 “g” 相隔好几行。当您最终输入了 fg 命令之后,bash 将显示正在 shell 中运行的命令(即命令列表),该命令仍然每隔两秒钟打印输出结果。

在将作业放入前台之后,您可以终止它,或者采取其他操作。在本例中,我们使用 Ctrl-c 终止时钟。

您可能想问为什么该作业为 job 2。在终止了指针式时钟之后,仅剩下一个运行的作业,它的作业编号为 1。所以将分配下一个可用的作业编号,因此我们的简易时钟为 job 2。

标准 I/O 和后台进程

在前面的例子中,来自 date 命令的输出被我们输入的 fg 命令产生的字符隔开。这导致一个有趣的问题。如果后台进程需要来自 stdin 的输入时,它会发生什么情况?

我们将在其下启动后台应用程序的终端进程称为控制终端

。除非被重定向到其他地方,否则来自后台进程的 stdout 和 stderr 流将被定向控制终端。类似地,后台任务希望收到来自控制终端的输入,但是控制终端不能将您输入的任何字符定向到后台进程的 stdin。对于这种情况,Bash shell 将暂停进程,从而使它停止执行。您可以将它放到前台并提供必要的输入。清单 7 显示了一个简单的例子,在该例中可以将命令列表放到后台。在片刻之后,按下 Enter 并看到关于进程已被停止的消息。将该命令列表放到前台,添加一行输入,最后按下 Ctrl-d 表示输入文件的结尾。在命令列表运行完成之后将显示我们创建的文件。

清单 7. 等待 stdin


ian@attic4:~$ (date; cat - > bginput.txt;date)&
[2] 5070
ian@attic4:~$ Tue Jan 19 10:33:13 EST 2010

[2]+ Stopped ( date; cat - > bginput.txt; date )
ian@attic4:~$
ian@attic4:~$ fg
( date; cat - > bginput.txt; date )
some text
more text
Tue Jan 19 10:33:31 EST 2010
ian@attic4:~$ cat bginput.txt
some text
more text





在注销之后运行进程

在实际操作中,您可能想要将后台进程的标准 I/O 流重定向到文件。这涉及到另一个问题:如果控制终端关闭或用户注销,进程会发生什么情况?答案取决于所使用的 shell。如果 shell 发送 SIGHUP(或 hangup)信号,那么很可能导致应用程序关闭。我们将在稍后讨论信号,现在考虑解决该问题的另一种方法。

nohup


nohup 命令用于启动一个忽略 hangup 信号的命令,并且将 stdout 和 stderr 附加到文件。默认的文件为 nohup.out 或 $HOME/nohup.out。如果文件不可被写入,将不运行命令。如果您想要将输出指定到其他位置,那么重定向 stdout 或 stderr,参见文章 “学习linux-流、管道、重定向”。

nohup 命令将不执行管道线或命令列表。您可以将管道线或列表保存在一个文件中,然后使用 sh(默认 shell)或 bash 命令运行它。本系列的另一篇文章将显示如何让脚本文件变成可执行文件,但是在本文中我们通过 sh 或 bash 命令运行脚本。清单 8 显示了如何为我们的简易数字时钟准备脚本。将时间写到文件中用途不大,并且会造成文件不断变大,因此我们将时钟设置为每 30 秒钟更新一次,而不是每秒钟更新一次。

清单 8. 在脚本中结合使用 nohup 和命令列表


ian@attic4:~$ echo "while sleep 30; do date;done">pmc.sh
ian@attic4:~$ nohup sh pmc.sh&
[2] 5485
ian@attic4:~$ nohup: ignoring input and appending output to `nohup.out'

ian@attic4:~$ nohup bash pmc.sh&
[3] 5487
ian@attic4:~$ nohup: ignoring input and appending output to `nohup.out'


如果我们显示 nohup.out 的内容,我们将看到一些行,并且每个行的出现都比它前面的第二个行晚 30 秒,如清单 9 所示。

清单 9. nohup 进程的输出


ian@attic4:~$cat nohup.out
Tue Jan 19 15:01:12 EST 2010
Tue Jan 19 15:01:26 EST 2010
Tue Jan 19 15:01:44 EST 2010
Tue Jan 19 15:01:58 EST 2010
Tue Jan 19 15:02:14 EST 2010
Tue Jan 19 15:02:28 EST 2010
Tue Jan 19 15:02:44 EST 2010
Tue Jan 19 15:02:58 EST 2010


老版本的 nohup 不将状态消息写到控制终端,因此如果您做错了事情,很难立即发现。如果您将 stdout 和 stderr 重定向到自己选择的文件,您将看到老版本中出现的行为。使用 . 发出命令比输入 sh 或 bash 更加容易。清单 10 显示了按照旧方式使用 nohup 会发生什么情况,但同时重定向了 stdout 和 stderr。在输入命令之后,您将看见一条消息,它表明启动的 job 4 的 PID 为 5853。但是,再次按 Enter 将看到另一条,表明该作业已终止,退出码为 126。

清单 10. 以错误的方式使用 nohup


ian@attic4:~$ nohup . pmc.sh >mynohup.out 2>&1 &
[4] 5853
ian@attic4:~$
[4]+ Exit 126 nohup . pmc.sh > mynohup.out 2>&1


清单 11 显示了 mynohup.out 的内容。该内容没有特别之处。您使用 nohup

在后台运行命令,并使用 source (.) 从文件运行读取命令,并在当前的 shell 中运行这些命令。这里需要记住的是,您可能需要按下 Enter 以允许 shell 显示后台作业退出状态,或者需要查看 nohup 的输出文件,看看哪里出错了。

清单 11.

自 nohup 的隐藏消息


ian@attic4:~$ cat mynohup.out
nohup: ignoring input
nohup: cannot run command `.': Permission denied


现在,让我们将话题转向进程的状态。如果您在此时想休息一下,那么请不要离开太久,因为您的两个作业在文件系统中创建的文件会不断变大。您可以使用 fg 命令来将它们放到前台,然后使用 Ctrl-c 终止它们。不过,如果您让它们多运行一段时间,将了解监控它们并与它们交互的其他方法。



监控进程

我们在前面简单介绍了 jobs 命令,并看到了如何使用它列出作业的 Process ID(或 PID)。

ps


我们还可以使用另一个命令 ps

显示进程状态信息的不同部分。记住,“ps” 是 “process status” 的首字母缩写。ps 命令接受 0 个或多个 PID 作为参数并显示相关联的进程状态。如果我们将 jobs 命令与 -p 选项一起使用,输出结果将是每个作业的 process group leader

的 PID。我们将使用该输出作为 ps 命令的参数,如清单 12 所示。

清单 12. 后台进程的状态


ian@attic4:~$ jobs -p
3878
5485
5487
ian@attic4:~$ ps $(jobs -p)
PID TTY STAT TIME COMMAND
3878 pts/1 S 0:06 xclock -d -update 1
5485 pts/1 S 0:00 sh pmc.sh
5487 pts/1 S 0:00 bash pmc.sh


如果您使用不带任何选项的 ps 命令,您将看到一个以您的终端作为控制终端的进程列表,如清单 13 所示。注意,该列表中不出现 pmc.sh 命令,但稍后您将看到为什么会这样。

清单 13. 使用 ps 命令显示状态


ian@attic4:~$ ps
PID TTY TIME CMD
2643 pts/1 00:00:00 bash
3878 pts/1 00:00:06 xclock
5485 pts/1 00:00:00 sh
5487 pts/1 00:00:00 bash
6457 pts/1 00:00:00 sleep
6467 pts/1 00:00:00 sleep
6468 pts/1 00:00:00 ps


可以通过几个选项控制所显示的信息,包括 -f (full),-j (jobs) 和 -l (long)。如果您不指定任何 PID,那么另一个比较有用的选项是 --forest,它以树结构的形式显示命令,以及每个进程对应的父进程。尤其是,您将看到前一个清单的 sleep 命令是您在后台运行的脚本的子进程。如果您刚好在不同的时间运行该命令,您将看到 date 命令列出在进程状态中,但对于该脚本,发生这种情况的几率不大。我们在清单 14 中显示其中一些选项。

清单 14. 更多状态信息


ian@attic4:~$ ps -f
UID PID PPID C STIME TTY TIME CMD
ian 2643 2093 0 Jan18 pts/1 00:00:00 bash
ian 3878 2643 0 09:17 pts/1 00:00:06 xclock -d -update 1
ian 5485 2643 0 15:00 pts/1 00:00:00 sh pmc.sh
ian 5487 2643 0 15:01 pts/1 00:00:00 bash pmc.sh
ian 6635 5485 0 15:41 pts/1 00:00:00 sleep 30
ian 6645 5487 0 15:42 pts/1 00:00:00 sleep 30
ian 6647 2643 0 15:42 pts/1 00:00:00 ps -f
ian@attic4:~$ ps -j --forest
PID PGID SID TTY TIME CMD
2643 2643 2643 pts/1 00:00:00 bash
3878 3878 2643 pts/1 00:00:06 \_ xclock
5485 5485 2643 pts/1 00:00:00 \_ sh
6657 5485 2643 pts/1 00:00:00 | \_ sleep
5487 5487 2643 pts/1 00:00:00 \_ bash
6651 5487 2643 pts/1 00:00:00 | \_ sleep
6658 6658 2643 pts/1 00:00:00 \_ ps


您已经具备一些使用 jobs 和 ps 命令监控进程的基本工具,在学习如何选择和排列进程之前,让我们简单看看其他两个监控命令。

free


free 命令显示系统的空闲内存和已用内存。默认情况下,使用的单位为千字节,但您可以使用选项 -b 替换为字节,使用 -k 替换为千字节,使用 -m 替换为兆字节,或使用 -g 替换为千兆字节。-t 选项显示整个行,带一个值的 -s 选项以指定的频率刷新信息。刷新时间的单位为秒,但可能是浮点值。清单 15 显示了两个例子。

清单 15. 使用 free 命令


ian@attic4:~$ free
total used free shared buffers cached
Mem: 4057976 1543164 2514812 0 198592 613488
-/+ buffers/cache: 731084 3326892
Swap: 10241428 0 10241428
ian@attic4:~$ free -mt
total used free shared buffers cached
Mem: 3962 1506 2456 0 193 599
-/+ buffers/cache: 713 3249
Swap: 10001 0 10001
Total: 13964 1506 12457

uptime


uptime 命令在一行内显示当前时间,系统运行时间,当前登录的用户,以及过去 1 分钟、5 分钟和 15 分钟系统的平均负载。清单 16 显示了一个例子。

清单 16. 显示正常运行时间信息


ian@attic4:~$ uptime
17:41:17 up 20:03, 5 users, load average: 0.00, 0.00, 0.00





根据需要选择和排列进程的显示方式

使用 ps

到目前为止所讨论的 ps 命令仅列出从终端会话启动的进程(注意清单14 中的第二个例子的 SID 列,即会话 ID 列)。要通过控制终端查看所有进程,使用 -a 选项。-x 选项显示不使用控制终端的进程,-e 选项显示每一个进程的信息。清单 17 显示带控制终端的所有进程的完整格式。

清单 17. 显示其他进程


ian@attic4:~$ ps -af
UID PID PPID C STIME TTY TIME CMD
ian 3878 2643 0 09:17 pts/1 00:00:06 xclock -d -update 1
ian 5485 2643 0 15:00 pts/1 00:00:00 sh pmc.sh
ian 5487 2643 0 15:01 pts/1 00:00:00 bash pmc.sh
ian 7192 5485 0 16:00 pts/1 00:00:00 sleep 30
ian 7201 5487 0 16:00 pts/1 00:00:00 sleep 30
ian 7202 2095 0 16:00 pts/0 00:00:00 ps -af


注意在 TTY 列中列出的控制终端。为了获取这个列表,我已切换到原先打开的终端窗口(pts/0),因此 ps -af 命令在 pts/0 下运行,尽管为本文创建的命令在 pts/1 下运行。

有许多针对 ps 的选项,包括控制显示哪些字段和以何种方式显示的选项。其他选项控制选择显示的进程,例如,为特定的用户(-u)或命令(-C)选择这些进程。在清单 18 中,列出了所有运行 getty 命令的进程;我们使用 -o 选项来自指定将要显示的列。我们将 user 选项添加到单纯使用 ps 获取到的常规列表,因此您可以看到哪个用户正在运行 getty。

清单 18. 谁正在运行 getty 命令?


ian@attic4:~$ ps -C getty -o user,pid,tty,time,comm
USER PID TT TIME COMMAND
root 1192 tty4 00:00:00 getty
root 1196 tty5 00:00:00 getty
root 1209 tty2 00:00:00 getty
root 1219 tty3 00:00:00 getty
root 1229 tty6 00:00:00 getty
root 1731 tty1 00:00:00 getty


有时您需要根据特定的字段对输出进行排序,您也可以使用 --sort 选项指定要排序的字段来实现该目的。默认值为以升序的方式进行排序(+),但您也可以指定以降序的方式进行排序(-)。清单 19 显示了最终的 ps 例子,其中使用作业的格式列出了所有进程,并且根据会话 ID 和命令名对输出进程排序。首先,我们使用默认的排序;其次,我们显式地指定这两种排序方式。

清单 19. 对来自 ps 命令的输出进行排序


ian@attic4:~$ ps -aj --sort -sid,+comm
PID PGID SID TTY TIME CMD
5487 5487 2643 pts/1 00:00:00 bash
9434 9434 2643 pts/1 00:00:00 ps
5485 5485 2643 pts/1 00:00:00 sh
9430 5485 2643 pts/1 00:00:00 sleep
9433 5487 2643 pts/1 00:00:00 sleep
3878 3878 2643 pts/1 00:00:10 xclock
8019 8019 2095 pts/0 00:00:00 man
8033 8019 2095 pts/0 00:00:00 pager
ian@attic4:~$ ps -aj --sort sid,comm
PID PGID SID TTY TIME CMD
8019 8019 2095 pts/0 00:00:00 man
8033 8019 2095 pts/0 00:00:00 pager
5487 5487 2643 pts/1 00:00:00 bash
9435 9435 2643 pts/1 00:00:00 ps
5485 5485 2643 pts/1 00:00:00 sh
9430 5485 2643 pts/1 00:00:00 sleep
9433 5487 2643 pts/1 00:00:00 sleep
3878 3878 2643 pts/1 00:00:10 xclock


和平常一样,查看手册页详细了解您可以指定多少个选项和字段,或者使用 ps --help 命令了解简要说明。

使用 top

如果您在一行内多次运行 ps,以便看看发生了什么变化,您可能需要改用 top 命令。它显示持续更新的进程列表和有用的摘要信息。清单 20 显示 top 命令输出的前几行。使用子命令 q 退出 top。

清单 20. 使用 top 显示进程


top - 16:07:22 up 18:29, 5 users, load average: 0.03, 0.02, 0.00
Tasks: 170 total, 1 running, 169 sleeping, 0 stopped, 0 zombie
Cpu(s): 2.1%us, 0.5%sy, 0.0%ni, 97.4%id, 0.0%wa, 0.0%hi, 0.0%si, 0.0%st
Mem: 4057976k total, 1543616k used, 2514360k free, 194648k buffers
Swap: 10241428k total, 0k used, 10241428k free, 613000k cached

PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
6820 ian 20 0 506m 78m 26m S 1 2.0 0:23.97 firefox
1381 root 20 0 634m 40m 18m S 1 1.0 2:06.74 Xorg
2093 ian 20 0 212m 15m 10m S 1 0.4 0:13.53 gnome-terminal
6925 ian 20 0 1118m 298m 19m S 1 7.5 1:07.04 java
6855 ian 20 0 73416 11m 8808 S 1 0.3 0:05.01 npviewer.bin
7351 ian 20 0 19132 1364 980 R 0 0.0 0:00.07 top
1 root 20 0 19584 1888 1196 S 0 0.0 0:00.74 init
2 root 15 -5 0 0 0 S 0 0.0 0:00.01 kthreadd


top 命令有许多子命令,其中开始学习时最有用的子命令为:

h
获得帮助
q
退出
top 命令
f
在显示结果中添加或删除字段
o
显示顺序
F
选择需要根据其进行排序的字段

查看手册页详细了解 top 的各种选项,包括如何根据内存使用或其他标准进行排序。清单 21 显示了一个根据虚拟内存使用量以降序的方式进行排序的例子。

清单 21. 对 top 命令的输出结果进行排序


top - 16:21:48 up 18:43, 5 users, load average: 0.16, 0.06, 0.01
Tasks: 170 total, 3 running, 167 sleeping, 0 stopped, 0 zombie
Cpu(s): 2.1%us, 0.8%sy, 0.0%ni, 96.6%id, 0.0%wa, 0.0%hi, 0.5%si, 0.0%st
Mem: 4057976k total, 1588940k used, 2469036k free, 195412k buffers
Swap: 10241428k total, 0k used, 10241428k free, 613056k cached

PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
6925 ian 20 0 1171m 338m 21m S 0 8.5 1:44.10 java
1381 root 20 0 634m 40m 18m S 0 1.0 2:13.63 Xorg
6820 ian 20 0 506m 83m 26m S 3 2.1 0:51.28 firefox
2004 ian 20 0 436m 23m 15m S 0 0.6 0:01.55 nautilus
2031 ian 20 0 419m 13m 10m S 0 0.3 0:00.11 evolution-alarm
2118 ian 20 0 372m 10m 7856 S 0 0.3 0:00.06 evolution-data-
2122 ian 20 0 344m 13m 10m S 0 0.3 0:00.10 evolution-excha
2001 ian 20 0 331m 22m 14m S 0 0.6 0:13.61 gnome-panel
1971 ian 20 0 299m 9.9m 7244 S 0 0.3 0:05.00 gnome-settings-
1989 ian 20 0 288m 15m 11m S 0 0.4 0:11.95 metacity
1954 ian 20 0 265m 5460 3412 S 0 0.1 0:00.28 pulseaudio





向进程发送信号

现在,让我们看一下 Linux 信号

,它是一种与进程通信的异步方式。我们已经提到 SIGHUP 信号并且使用了 Ctrl-c 和 Ctrl-z 组合键,它们是向进程发送信号的其他方式。发送信号的常见方式是使用 kill 命令。

使用 kill 命令发送信号

kill 命令将信号发送到指定的作业或进程。清单 22 显示使用 SIGTSTP 和 SIGCONT 信号来停止和恢复后台作业。使用 SIGTSTP 信号等效于使用 fg 命令将作业放到前台并使用 Ctrl-z 暂停它。使用 SIGCONT 类似于使用 bg 命令。

清单 22. 停止和重新启动后台作业


ian@attic4:~$ kill -s SIGTSTP %1

[1]+ Stopped xclock -d -update 1
ian@attic4:~$ jobs -l
[1]+ 3878 Stopped xclock -d -update 1
[2] 5485 Running nohup sh pmc.sh &
[3]- 5487 Running nohup bash pmc.sh &
ian@attic4:~$ kill -s SIGCONT 3878
ian@attic4:~$ jobs -l
[1] 3878 Running xclock -d -update 1 &
[2]- 5485 Running nohup sh pmc.sh &
[3]+ 5487 Running nohup bash pmc.sh &


在本例中,我们使用作业指示 (%1) 停止 xclock 进程,然后使用进程 ID(PID)重新启动(继续)它。如果您停止 job %2,然后使用 tail 及其后面的 -f 选项,您将看到仅有一个进程正在更新 nohup.out 文件。

您可以使用 kill -l 在系统中显示许多其他信号。其中一些信号用于报告错误,比如非法操作代码,浮点异常,或试图访问进程无权访问的内存。注意,信号也有编号(比如 20)和名称(比如 SIGTSTP)。您可以使用连字符 (-) 前面的编号,也可以使用 -s 选项和信号名。在我的系统中,我使用 kill -20,而不是 kill -s SIGTSTP。在确定哪个编号对应哪个信号之前,您应该检查系统中信号的编号。

信号处理程序和进程终止

您已经看到使用 Ctrl-c 可以终止进程。事实上,它向进程发送一个 SIGINT(或中断)信号。如果您使用不带任何信号名的 kill,它将发送一个 SIGTERM 信号。在大多数情况下,这两个信号是等效的。

您已经看到 nohup 命令可以让进程避开 SIGHUP 信号。一般情况下,进程可以实现一个信号处理程序

捕捉

信号。因此进程可以实现信号处理程序来捕捉 SIGINT 或 SIGTERM。因为信号处理程序知道发送的信号是什么,所以它可能选择忽略 SIGINT,并且在收到(比如)SIGTERM 时才终止。清单 23 显示了如何将 SIGTERM 信号发送到 job %2。注意,在发送信号之后,进程状态立即显示为 “Terminated”。如果我们使用 SIGINT,将显示为 “Interrupt”。在片刻之后,将开始清除进程,作业也不再出现在作业列表中。

清单 23. 使用 SIGTERM 终止进程


ian@attic4:~$ kill -s SIGTERM %2
ian@attic4:~$
[2]- Terminated nohup sh pmc.sh
ian@attic4:~$ jobs -l
[1]- 3878 Running xclock -d -update 1 &
[3]+ 5487 Running nohup bash pmc.sh &


信号处理程序给进程提供了很大的灵活性。进程可以完成其常规工作,并且为了实现特定目的可以被信号中断。除了允许进程捕捉终止请求和采取可能的行动(比如关闭正在进行的文件或检查点事务)之外,信号还通常用于告诉守护进程重新读取其配置文件和重启操作。您在添加新的打印程序时可能要更改网络参数或 line printer daemon (lpd),这时可能需要进行该操作。

无条件终止进程

有一些信号是无法捕获的,比如某些硬件异常。您最常用的 SIGKILL 就不能被信号处理程序捕捉到,因此需要无条件终止它。总而言之,仅当所有办法都无法终止进程时,才选择无条件终止它。



注销和 nohup

还记得吗,使用 nohup 允许您在注销之后仍然让进程继续运行。让我们先注销然后再次登录。在登录之后,使用 jobs 和 ps 检查仍然在运行的简易时钟进程,和前面所做的一样。该操作的输出如清单 24 所示。

清单 24. 重新登录


ian@attic4:~$ jobs -l
ian@attic4:~$ ps -a
PID TTY TIME CMD
10995 pts/0 00:00:00 ps


这次我们在 pts/0 中运行,但仅出现 ps 命令,而没有出现我们的作业。不过,它们并没有丢失。假设您不记得是否终止了使用 bash 启动的 nohup 作业或其他使用 bash 启动的作业。您在前面了解到如何找到运行 getty 命令的进程,因此您可以使用相同的方法来显示 SID、PID、PPID 和命令字符串。然后,您可以使用 -js 选项显示会话中的所有进程。清单 25 显示了结果。想想其他您曾用于找到这些进程的方法,比如搜索用户名然后使用 grep 进行过滤。

清单 25. 找出丢失的命令


ian@attic4:~$ ps -C bash -C sh -o pid,sid,tname,cmd
PID SID TTY CMD
5487 2643 ? bash pmc.sh
7050 7050 pts/3 -bash
10851 10851 pts/0 bash
ian@attic4:~$ ps -js 2643
PID PGID SID TTY TIME CMD
5487 5487 2643 ? 00:00:00 bash
11197 5487 2643 ? 00:00:00 sleep


注意,pmc.sh 仍然运行,但现在控制 TTY 多了一个问号 (?)。

既然您现在已经学会了如何终止进程,您应该能够通过 PID 和 kill 命令终止仍然在运行的简易时钟进程。




赞(0)    操作        顶端 
总帖数
1
每页帖数
101/1页1
返回列表
发新帖子
请输入验证码: 点击刷新验证码
您需要登录后才可以回帖 登录 | 注册
技术讨论