如果用户在 UNIX 操作系统上执行了一个程序,那么操作系统会为这个程序创建一个运行它的特定环境。这个环境包含系统运行该程序所需的一切资源,使得好像系统中没有运行其他程序一样。
用户如果在 UNIX 操作系统中输入一个指令,操作系统就会创建(启动)一个相应的进程。比如,如果用户希望使用 ls 指令来列出目录内的文件列表时,系统就启动了一个进程来完成这个任务。简单的说,进程就是一个可执行程序的实例。
操作系统通过一个 5 位的 ID 号码来追踪进程,这个 ID 号码 通常被称为pid 或进程 ID。操作系统中的每一个进程都有唯一 pid。
由于所有的进程 ID 是循环使用的,所以 pid 是会重复的。不过,在操作系统中,不存在两个进程拥有统一进程 ID 的情况。
如果用户创建一个进程(执行一个指令),那么可以两种方式来运行它。
默认情况下,任何一个用户创建的进程都会在前端执行。该进程可以从键盘获取输入信息并且可以将执行结果反馈到显示器上。
我们可以使用 ls 指令来观察这个过程。如果用户希望列出当前目录下的所有文件,用户需要在终端命令行键入如下指令:
$ls ch*.doc
这个指令将会显示所有文件名称以 ch 开头,以 .doc
结尾的文件。
ch01-1.doc ch010.doc ch02.docch03-2.doc
ch04-1.doc ch040.doc ch05.docch06-2.doc
ch01-2.doc ch02-1.doc
该指令对应的进程在前台进行,输出结果直接显示在显示屏上,如果 ls 执行需要获取输入,那么该进程会等待来自键盘的输入信息。
当程序在前台执行的时候,用户无法执行其他的指令(创建其他的进程),这是因为系统会提示其他进程无法创建直到当前进程执行完毕。
后台进程不需要键盘输入的信息就可以执行。如果后台进程需要键盘等外设的输入信息的话,那么它会等待。
后台进程的优点是用户可以执行其他的指令。用户此时不需要等待进程结束就可以执行其他的进程。
开启一个后台进程的最简单的方法就是在指令的末尾添加 &
标识符。
$ls ch*.doc &
这个指令也会示所有文件名称以 ch 开头,以 .doc
结尾的文件。
ch01-1.doc ch010.doc ch02.docch03-2.doc
ch04-1.doc ch040.doc ch05.docch06-2.doc
ch01-2.doc ch02-1.doc
如果这里的 ls 指令希望得到输入信息,它会转换为停止状态直到用户将他转到前台并获取到从键盘来的输入信息。
第一行显示了后台进程的信息——作业号和进程 ID,用户需要使用作业号来完成前景和后台之间的切换。
如果用户按下回车键,可以看到如下信息:
[1] + Done ls ch*.doc &
$
第一行表示 ls 指令的后台进程已经成功执行。第二行提示可以执行其他的指令。
可以使用 ps 指令来显示当前操作系统处于执行状态的进程,结果如下:
$ps
PID TTY TIMECMD
18358 ttyp3 00:00:00sh
18361 ttyp3 00:01:31abiword
18789 ttyp3 00:00:00ps
使用 ps 指令时,通常会选择 -f 选项。该选项可以显示更为详细的内容。
$ps -f
UID PID PPID C STIME TTY TIME CMD
amrood 6738 3662 0 10:23:03 pts/6 0:00 first_one
amrood 6739 3662 0 10:22:54 pts/6 0:00 second_one
amrood 3662 3657 0 08:10:53 pts/6 0:00 -ksh
amrood 6892 3662 4 10:51:50 pts/6 0:00 ps -f
下面是 -f
选项列出内容的的相关解释。
列名称 | 意义 |
---|---|
UID | 执行该进程的用户ID |
PID | 进程编号 |
PPID | 该进程的父进程编号 |
C | 该进程所在的CPU利用率 |
STIME | 进程执行时间 |
TTY | 进程相关的终端类型 |
TIME | 进程所占用的CPU时间 |
CMD | 创建该进程的指令 |
如下是其他配合 ps 指令的选项:
选项 | 意义 |
---|---|
-a | 显示所有用户的信息 |
-x | 显示关于没有终端的进程的信息 |
-u | 显示类似 -f 的其他附加信息 |
-e | 显示扩展信息 |
用户可以使用多种方式来停止一个进程。通常情况下,可以通过终端指令来完成,比如,同时按下 CTRL+C 键就可以停止当前执行的指令。这种方式仅在程序以前台的方式执行的情况下起作用。
如果一个进程以后台的方式在执行,那么首先用户需要通过 ps 指令来获取它的作业编号,然后用户可以使用 kill 指令来杀掉该进程。如下:
$ps -f
UID PID PPID C STIMETTY TIME CMD
amrood 6738 3662 0 10:23:03 pts/6 0:00 first_one
amrood 6739 3662 0 10:22:54 pts/6 0:00 second_one
amrood 3662 3657 0 08:10:53 pts/6 0:00 -ksh
amrood 6892 3662 4 10:51:50 pts/6 0:00 ps -f
$kill 6738
Terminated
这里的 kill 指令收终止指令为 first_one 对应的进程。如果某个进程无视常规的 kill 指令。用户可以使用 kill -9 后跟进程编号的方式来终止指令,如下:
$kill -9 6738
Terminated
UNIX 系统中的每一个进程都有两个 ID 号码:进程 ID(pid)和父进程 ID(ppid).系统中的每一个用户进程均有父进程。
大部分使用 shell 执行的指令均有他们各自的父进程。使用 ps -f
指令可以显示出每个进程相对应的进程 ID和其父进程 ID.
通常情况下,当某个子进程被杀掉后,其父进程会被 SIGCHILD 信号通知。然后,该父进程会做一些必要的操作或者启动一个新的子进程。然而,有时候是父进程先于子进程被杀掉。这种情况下,被称为“所有进程的父进程”的 init 进程就称为该子进程的父进程。这些子进程也称为孤儿进程。
当某个进程被杀掉后,ps 指令列出的列表里显示该进程标志位 Z 状态。它就是一个僵尸进程。该进程处于死亡状态并且不会被再次使用。这些进程不同于孤儿进程。他们是已经完成任务的进程,但是仍在进程表中留有一个入口。
守护进程是操作系统相关的后台进程,他们通常以 root 权限执行,并且会相应其他进程的请求。
守护进程没有控制终端。它也不能打开 /dev/tty
。如果用户使用"ps -ef" 指令来查看 tty 域,所有的守护进程在该域都会显示?。
更详细的来讲,守护进程就是执行在后台的进程,且它会等待某个事件的发生,从而相应该事件。比如打印机守护进程一直在等待打印的指令。
如果用户的某个程序需要长时间的执行,那么可以将它设计为守护进程的启动方式。
top 指令是用于显示以不同条件排序进程的指令。
它是一个频繁更新的交互式诊断工具,会动态的显示如下和相关进程的如下信息:物理内存、虚拟内存、CPU 利用率、负载率。
下面是一个简单的例子来执行 top 指令,且查看不同继承的CPU使用率。
$top
后台的且阻塞状态的进程通常使用作业编号来维护。该作业编号不同于进程编号。
此外,作业可以包含多个进程,这些进程可以串行执行,也可以并行执行,所以使用作业编号比跟踪单个的进程会更加简单。