Chinaunix首页 | 论坛 | 博客
  • 博客访问: 132946
  • 博文数量: 75
  • 博客积分: 3483
  • 博客等级: 中校
  • 技术积分: 820
  • 用 户 组: 普通用户
  • 注册时间: 2010-01-07 08:31
文章分类

全部博文(75)

文章存档

2011年(53)

2010年(22)

我的朋友

分类:

2011-01-10 15:42:23

您可以在自己的命令行,很方便地体验分叉操作。首先,打开一个新的 xterm。(您现在可能会认识到,xterm 就是它本身的进程,在 xterm 中,shell 是由 xterm 产生的一个独立进程)。接下来,输入:

ps  -o pid,ppid,uname,command,state,stime,time

您应该会看到类似这样的内容:

  PID  PPID USER     COMMAND          S STIME     TIME
16351 16350 mstreic  -bash            S 11:23 00:00:00
16364 16351 mstreic  ps -o pid,ppid,u R 11:24 00:00:00

从该列表的 PPID 字段中,我们知道 ps 命令是 bash shell 的子进程。(-bash 中的连字符说明 shell 实例是一个登录 shell。)为了运行 ps,bash 会分叉,创建一个新进程;新进程通过使用执行,使其本身得以重生,转化为 ps 的一个新的实例。

这里是另一个可供尝试的实验。键入:

sleep 10 & sleep 10 & sleep 10 & ps  -o pid,ppid,uname,command,state,stime,time

您应该会看到类似这样的内容:

$ sleep 10 & sleep 10 & sleep 10 & ps  -o pid,ppid,uname,command,state,stime,time
  PID  PPID USER     COMMAND          S STIME     TIME
16351 16350 mstreic  -bash            S 11:23 00:00:00
16843 16351 mstreic  sleep 10         S 11:42 00:00:00
16844 16351 mstreic  sleep 10         S 11:42 00:00:00
16845 16351 mstreic  sleep 10         S 11:42 00:00:00
16846 16351 mstreic  ps -o pid,ppid,u R 11:42 00:00:00

命令行生成四个新进程。在每个 sleep 命令后键入 &,在后台运行每一个命令,或与 Shell 并行。 ps 是生成的另一个进程,但它是在前台运行的,可以防止 shell 在该进程终止之前运行其他命令。而且,如 PPID 的值所示,所有四个进程都是 Shell 的后代。三个 sleep 命令都被标为 S,因为没有哪个进程会在它们睡眠时使用资源。

为了方便起见,shell 会持续跟踪它生成的所有后台进程。键入 jobs,可以看到一个列表:

$ sleep 10 & sleep 10 & sleep 10 & 
[1] 16843
[2] 16844
[3] 16845

$ jobs
[1]   Running                 sleep 10 &
[2]   Running                 sleep 10 &
[3]   Running                 sleep 10 &

此处,为了方便起见,三个工作分别用标签标为 1,2 和 3。数字 16843、16844 和 16845 分别是每个进程的进程 ID。因此,后台任务 1 即为进程 ID 16843。

您可以利用这些标签,从命令行操作您的后台工作。例如,如要终止某个命令,键入 kill %N ,其中 N 是该命令的标签。如要将某个命令由后台移到前台,请键入 fg %N

$ sleep 10 & sleep 10 & sleep 10 &
[7] 17741
[8] 17742
[9] 17743

$ kill %7
$ jobs
[7]   Terminated              sleep 10
[8]-  Running                 sleep 10 &
[9]+  Running                 sleep 10 &

$ fg %8
sleep 10

从命令行中同时异步运行多个命令,是处理您自己的任务集的好方法。一个长时间运行的工作(例如,系统管理的数值计算或大型程序的编译)最适合放在后台。为了捕获每个后台命令的输出,请考虑使用重定向操作符 >>&>>>>&,将输入重定向到某个文件。当后台命令结束后,shell 会在下一个提示符之前显示一条警告消息:

$ whoami
mstreicher
[8]-  Done                    sleep 10
[9]+  Done                    sleep 10
$

某些进程会一直存活(如 init),而某些进程会以新的形式重生(如您的 shell)。最终大多进程都会因自然原因(即程序运行结束)而消亡。

此外,您还可以将某个进程放在一个挂起的动作序列中,等待被再次激活。正如先前的示例所示,您可以用 kill 提前终止某个进程。

当某个命令在前台运行时,如果您希望将它挂起,请按 Ctrl + Z

$ sleep 10
(Press Control-Z)
[1]+  Stopped                 sleep 10

$ ps
  PID  PPID USER     COMMAND          S STIME     TIME
18195 16351 mstreic  sleep 10         T 12:44 00:00:00

Shell 已将命令挂起,为了方便起见,还为它分配了一个标签。您可以像先前那样使用这个标签,以终止工作或让工作返回前台。您还可以使用 bg 命令在后台恢复这个进程:

bg %1
[1]+ sleep 10 &

当某个命令在前台运行时,如果您想终止它,请按 Ctrl + C

$ sleep 10
(Press Control-C
$ jobs
$

您的 Shell 能使进程的挂起和终止变得更容易,但在 Shell 单纯的外表下,却隐藏着复杂的一面。在内部,Shell 使用 UNIX 信号来影响进程的状态。信号是一个事件,它被用来向某个进程发出警报。操作系统生成许多信号,但您可以将信号从一个进程发送到另一个进程,甚至能让某个进程给自己发送信号。

UNIX 包括多种信号,它们大多都有特殊目的。例如,如果您将信号 SIGSTOP 发送到某个进程,该进程将挂起。(要获取信号的完整列表,请键入 man 7 signal 或键入 kill -L)。您可以用 kill 命令发送信号。

$ sleep 20 &
[1] 19988

$ kill -SIGSTOP 19988

$ jobs
[1]+  Stopped                 sleep 20

起初,sleep 命令在后台启动,其进程 ID 为 19988。在发送 SIGSTOP 之后,该进程会改变状态,变为挂起或停止。发送另一个信号 SIGCONT,重新激活进程,该进程将从上次停止的地方继续执行。

也就是说,每次您按 Ctrl + Z 时,您的 shell 将向前台发送 SIGSTOP 信号。bg 命令发送 SIGCONT。而 Ctrl + C 则会发送 SIGTERM,要求立即终止进程。

一些信号可以被某个进程阻塞,应用程序可以通过设计,显式地“捕捉 (catch)”信号,并以一种特殊的方式对每个事件作出反应。例如,系统服务 xinetd 会按需要启动其他网络服务,它在收到 SIGHUP 时会重新读取它的配置文件。在 Linux 中,向 init 发送信号,可能会改变系统的运行级别,甚至会导致系统关闭。.(这里有一个问题:kill %1kill 1 有什么区别?

进程甚至可以给自己发送信号。想像一下,您正在编写一个游戏,想留给用户五秒钟时间作出反应。您的代码可以设置一个五秒钟的定时器,接下来继续进行重绘屏幕等操作。当定时器的时间耗尽后,将有一个 SIGALRM 信号被送回您的进程。呯!时间到!

(这里提供了问题的答案:kill %1 会终止标签为 1 的后台工作。kill 1 会终止 init,当必须关闭计算机时,将向操作系统发送这个信号。)

在特殊情况下,操作系统还可以将一些其他信号传送给进程。内存违例会引发 SIGSEGV 信号,立即终止进程,并留下一个内核转储。有一个特殊的信号 SIGKILL 是无法被阻塞或捕捉的,它会立即终止某个进程。

和 UNIX 中许多其他资源一样,您只能向您拥有的进程发送信号。这可以防止您终止重要的系统服务和其他用户的进程。超级用户 root 可以向任何进程发送信号。

阅读(409) | 评论(0) | 转发(0) |
0

上一篇:MY FUNS 1

下一篇:solution of problem 1

给主人留下些什么吧!~~