| Linux进程管理和文本编辑 |
|
| |
|
摘要:本讲主要介绍Linux系统中进程和线程的概念、进程状态、信号机制、有关进程的常用命令、系统引导,以及vi编辑器的使用方法。
Linux是一个多用户、多任务的操作系统,这就意味着多个用户可以同时使用一个操作系统,而每个用户又可以同时运行多个命令。在这样的系统中,各种计算机资源(如文件、内存、CPU等)的分配和管理都以进程为单位。为了协调多个进程对这些共享资源的访问,操作系统要跟踪所有进程的活动,以及它们对系统资源的使用情况,实施对进程和资源的动态管理。
进程和线程
1.进程及其状态 在多道程序工作环境下,各个程序是并发执行的,它们共享系统资源,共同决定这些资源的状态。彼此间相互制约、相互依赖,因而呈现出并发、动态及互相制约等新的特征。这样,用程序这个静态概念已不能如实反映程序活动的这些特征。为此,人们引进了进程(Process)这一新概念,来描述程序动态执行过程的性质。
简单说来,进程就是程序的一次执行过程。它有着走走停停的活动规律。进程的动态性质是由其状态变化决定的。通常在操作系统中,进程至少要有三种基本状态,它们是运行态、就绪态和封锁态(或阻塞态)。
运行状态是指当前进程已分配到CPU,它的程序正在处理器上执行时的状态。处于这种状态的进程个数不能大于CPU的数目。在一般单CPU机制中,任何时刻处于运行状态的进程至多有一个。
就绪状态是指进程已具备运行条件,但因为其它进程正占用CPU,所以暂时不能运行而等待分配CPU的状态。一旦把CPU分给它,立即就可运行。在操作系统中,处于就绪状态的进程数目可以是多个。
封锁状态是指进程因等待某种事件发生(例如等待某一输入、输出操作完成,等待其它进程发来的信号等)而暂时不能运行的状态。也就是说,处于封锁状态的进程尚不具备运行条件,即使CPU空闲,它也无法使用。这种状态有时也称为不可运行状态或挂起状态。系统中处于这种状态的进程可以是多个的。
进程的状态可依据一定的条件和原因而变化,如图1所示。一个运行的进程可因某种条件未满足而放弃CPU,变为封锁状态;以后条件得到满足时,又变成就绪态;仅当CPU被释放时才从就绪态进程中挑选一个合适的进程去运行,被选中的进程从就绪态变为运行态。挑选进程、分配CPU这个工作是由进程调度程序完成的。
另外,在Linux系统中,进程(Process)和任务(Task)是同一个意思。所以,在内核的代码中,这两个名词常常混用。
2.Linux进程状态
在Linux系统中,进程有以下几个状态: ◆运行态(TASK_RUNNING) 此时,进程正在运行(即系统的当前进程)或者准备运行(即就绪态)。 ◆等待态 此时进程在等待一个事件的发生或某种系统资源。Linux系统分为两种等待进程:可中断的(TASK_INTERRUPTIBLE)和不可中断的(TASK_UNINTERRUPTIBLE)。可中断的等待进程可以被某一信号(Signal)中断;而不可中断的等待进程不受信号的打扰,将一直等待硬件状态的改变。 ◆停止态(TASK_STOPPED) 进程被停止,通常是通过接收一个信号。正在被调试的进程可能处于停止状态。 ◆僵死态(TASK_ZOMBIE) 由于某些原因被终止的进程,但是该进程的控制结构task_struct仍然保留着。
图2示出Linux系统中进程状态的变化关系。
 图1 进程状态及其变化
 图2 Linux进程状态的变化
3.进程的模式和类型 在Linux系统中,进程的执行模式划分为用户模式和内核模式。如果当前运行的是用户程序、应用程序或者内核之外的系统程序,那么对应进程就在用户模式下运行;如果在用户程序执行过程中出现系统调用或者发生中断事件,就要运行操作系统(即核心)程序,进程模式就变成内核模式。在内核模式下运行的进程可以执行机器的特权指令;而且,此时该进程的运行不受用户的干预,即使是root用户也不能干预内核模式下进程的运行。
按照进程的功能和运行的程序分类,进程可划分为两大类:一类是系统进程,只运行在内核模式,执行操作系统代码,完成一些管理性的工作,例如内存分配和进程切换;另外一类是用户进程,通常在用户模式中执行,并通过系统调用或在出现中断、异常时进入内核模式。
用户进程既可以在用户模式下运行,也可以在内核模式下运行,如图3所示。
 图3 用户进程的两种运行模式
4.Linux线程 线程是和进程紧密相关的概念。一般说来,Linux系统中的进程应具有一段可执行的程序、专用的系统堆栈空间、私有的“进程控制块”(即task_struct数据结构)和独立的存储空间。Linux系统中的线程只具备前三个组成部分,而缺少自己的存储空间。
线程可以看作是进程中指令的不同执行路线。例如,在文字处理程序中,主线程负责用户的文字输入,而其它线程可以负责文字加工的一些任务。往往也把线程称作轻型进程。Linux系统支持内核空间的多线程,但它与大多数操作系统不同,后者单独定义线程,而Linux则把线程定义为进程的“执行上下文”。
有关进程管理的命令
Linux命令的执行是通过进程实现的。当在提示符之后输入一个命令或可执行文件的名字,一按回车键,这个命令就开始执行了。在操作系统中,为了执行这个命令,往往要创建相应的进程,通过进程的活动来完成一个预定的任务。其实,在Linux中,通常执行任何一个命令都会创建一个或多个进程。当进程完成了预期的目标自行终止时,该命令也就执行完了。不但用户可以创建进程,系统程序也可以创建进程。可以说,一个运行着的操作系统就是由许许多多的进程组成的。
1.ps命令 ps命令是查看进程状态的最常用的命令,它可以提供关于进程的许多信息。根据显示的信息可以确定哪个进程正在运行、哪个进程被挂起、遇到了哪些困难、进程已运行了多久、进程正在使用的资源、进程的相对优先级,以及进程的标识号(PID)。所有这些信息对用户都很有用,对于系统管理员来说更为重要。
ps命令的一般格式是:ps [选项]
ps的选项有几种类型。Unix 98的选项可以成组,并且在选项字母前必须有一个连字符(-);BSD的选项可以成组,并且在选项字母前没有连字符;而GNU的长选项在选项字母前有两个连字符。
以下是ps命令常用的选项及其含义: -a 显示系统中与tty相关的(除会话组长之外)所有进程的信息。 -e 显示所有进程的信息。 -f 显示进程的所有信息。 -l 以长格式显示进程信息。 r 只显示正在运行的进程。 u 显示面向用户的格式(包括用户名、CPU及内存使用情况等信息) 。 x 显示所有非控制终端上的进程信息。 --pid 显示由进程ID指定的进程的信息。 --tty 显示指定终端上的进程的信息。
◆直接用ps命令可以列出每个与当前Shell有关的进程基本信息:
$ ps
PID TTY TIME CMD
1542 pts/0 00:00:00 bash
1590 pts/0 00:00:00 ps
上面代码中,各字段的含义如下: PID 进程标识号。 TTY 该进程建立时所对应的终端,“?”表示该进程不占用终端。 TIME 报告进程累计使用的CPU时间。注意,尽管觉得有些命令(如sh)已经运转了很长时间,但是它们真正使用CPU的时间往往很短。所以,该字段的值往往是00:00。 CMD 执行进程的命令名。
◆利用选项-ef可以显示系统中所有进程的全面信息:
$ ps -ef
UID PID PPID C STIME TTY TIME CMD
root 1 0 0 20:42 ? 00:00:05 init
root 2 1 0 20:42 ? 00:00:00 [keventd]
root 3 1 0 20:42 ? 00:00:00 [kapmd]
root 4 1 0 20:42 ? 00:00:00 [ksoftirqd_CPU0]
……
mengqc 978 1 0 20:43 ? 00:00:00 kdeinit:Running…
……
mengqc 1541 978 0 20:44 ? 00:00:00 rxvt
mengqc 1542 1541 0 20:44 pts/0 00:00:00 bash
……
mengqc 1594 1542 0 21:39 pts/0 00:00:00 ps -ef
上面各项的含义是: UID 进程属主的用户ID号。 PID 进程ID号。 PPID 父进程的ID号。 C 进程最近使用CPU的估算。 STIME 进程开始时间,以“小时:分:秒”的形式给出。 TTY 该进程建立时所对应的终端,“?”表示该进程不占用终端。 TIME 报告进程累计使用的CPU时间。注意,尽管觉得有些命令(如sh)已经运转了很长时间,但是它们真正使用CPU的时间往往很短。所以,该字段的值往往是0:00。 CMD 是command(命令)的缩写,往往表示进程所对应的命令名。
◆利用下面的命令可以显示所有终端上所有用户的有关进程的所有信息:
$ ps -aux
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
root 1 0.1 0.1 1276 468 ? S 20:42 0:05 init
root 2 0.0 0.0 0 0 ? SW 20:42 0:00 [keventd]
root 3 0.0 0.0 0 0 ? SW 20:42 0:00 [kapmd]
root 4 0.0 0.0 0 0 ? SWN 20:42 0:00 [ksoftirqd_CPU0]
……
mengqc 978 0.0 3.1 20284 8156 ? S 20:43 0:00 kdeinit:Running…
……
mengqc 1541 0.0 0.6 6288 1720 ? R 20:44 0:00 rxvt
mengqc 1542 0.0 0.5 5588 1440 pts/0 S 20:44 0:00 bash
……
mengqc 1599 0.0 0.3 2676 792 pts/0 R 21:55 0:00 ps -aux
上面列表中包含了一些新的项: USER 启动进程的用户。 %CPU 运行该进程占用CPU的时间与该进程总的运行时间的比例。 %MEM 该进程占用内存和总内存的比例。 VSZ 虚拟内存的大小,以KB为单位。 RSS 占用实际内存的大小,以KB为单位。 STAT 表示进程的运行状态,包括以下几种代码: D 不可中断的睡眠; R 就绪(在可运行队列中); S 睡眠; T 被跟踪或停止; Z 终止(僵死)的进程。
对于BSD格式,还包括以下代码: W 没有内存驻留页; < 高优先权的进程; N 低优先权的进程; L 有锁入内存的页面(用于实时任务或定制I/O任务); START 开始运行的时间。
2.kill命令 通常终止一个前台进程可以使用“Ctrl+C”组合键。但是,对于一个后台进程就须用kill命令来终止。kill命令是通过向进程发送指定的信号来结束相应进程。默认情况下,采用编号为15的TERM信号。TERM信号将终止所有不能捕获该信号的进程。对于那些可以捕获该信号的进程就要用编号为9的KILL信号,强行杀掉该进程。
kill命令的一般格式是:
kill [-s 信号|-p ] [-a] 进程号...
kill -l [信号]
其中选项各选项的含义如下: -s 指定需要发送的信号,既可以是信号名(如KILL),也可以是对应信号的号码(如9) 。 -p 指定kill命令只是显示进程的pid(进程标识号),并不真正发出结束信号。 -l 显示信号名称列表,这也可以在/usr/include/linux/signal.h文件中找到。
使用kill命令时应注意: (1)kill命令可以带信号号码选项,也可以不带。如果没有信号号码,kill命令就会发出终止信号(TERM)。这个信号可以杀掉没有捕获到该信号的进程,也可以用kill向进程发送特定的信号。例如:kill -2 1234
它的效果等同于在前台运行PID为1234的进程的时候,按下“Ctrl+C”。但是普通用户只能使用不带signal参数的kill命令,或者最多使用-9信号。
(2)kill可以带有进程ID号作为参数。当用kill向这些进程发送信号时,必须是这些进程的主人。如果试图撤销一个没有权限撤销的进程,或者撤销一个不存在的进程,就会得到一个错误信息。 (3)可以向多个进程发信号,或者终止它们。 (4)当kill成功地发送了信号,Shell会在屏幕上显示出进程的终止信息。有时这个信息不会马上显示,只有当按下回车键使Shell的命令提示符再次出现时才会显示出来。 (5)信号使进程强行终止常会带来一些副作用,比如数据丢失或终端无法恢复到正常状态。发送信号时必须小心,只有在万不得已时才用kill信号(9),因为进程不能首先捕获它。
要撤销所有的后台作业,可以键入“kill 0”。因为有些在后台运行的命令会启动多个进程,跟踪并找到所有要杀掉的进程的PID是件很麻烦的事。这时,使用“kill 0 ”来终止所有由当前Shell启动的进程是个有效的方法。
用kill命令终止一个已经阻塞的进程,或者一个陷入死循环的进程,一般可以首先执行以下命令: $ find / -name core -print > /dev/null 2>&1&
这是一条后台命令,执行时间较长。现在决定终止该进程。为此,运行ps命令来查看该进程对应的PID。例如,该进程对应的PID是1651,现在可用kill命令杀死这个进程: $ kill 1651
再用ps命令查看进程状态时,就会发现find进程已经不存在了。
3.sleep命令 sleep命令的功能是使进程暂停执行一段时间。其一般格式是: sleep 时间值
其中,“时间值”参数以秒为单位,即使进程暂停由时间值所指定的秒数。此命令大多用于Shell程序设计中,使两条命令执行之间停顿指定的时间。
下面的命令行使进程先暂停100秒,然后查看用户mengqc是否在系统中: $ sleep 100; who | grep 'mengqc'
信号机制
信号(Signal,亦称作软中断) [1] [2] [3] 下一页
 |
频道声明:本频道的文章除部分特别声明禁止转载的专稿外,可以自由转载.但请务必注明出出处和原始作者 文章版权归本频道与文章作者所有.对于被频道转载文章的个人和网站,我们表示深深的谢意。
| 原始作者:佚名 |
录入时间:2007-1-2 3:34:54 |
| 信息来源:不详 |
投稿信箱:itqoo@126.com |
|
|
 |
|
|
|
| 教程录入:itqoo 责任编辑:itqoo |
|
上一个教程: proc文件系统
下一个教程: 全面移植2.6内核的应用程序 |
| 【字体:小 大】【发表评论】【加入收藏】【告诉好友】【打印此文】【关闭窗口】 |