您好,欢迎访问三七文档
第8章进程管理Linux为用户所做的一切工作都是通过Linux进程来完成的。当用户登录时,shell是一个进程;当用户运行一个编辑器时,这个编辑器是一个进程。用户运行的任何命令几乎都是一个进程。进程调用潜伏在后台的“精灵”,并等待它执行一些需要的工作,在执行期间无需干预。例如,当用户使用lp或lpr命令打印一些文件时,把数据送到打印机的实际工作就是由一个“精灵”完成的。正常情况下,所有的进程都自动产生,用户不必过多注意它。然而有时候一个程序可能误入歧途,而用户又不能正常退出它。如果用户使用的是一台运行DOS或Macintoch的个人计算机,那么对一个摆脱不掉的程序的通常处理是重新启动计算机;但如果用户运行的是Linux,那么为了一个不能退出的程序重新启动计算机就有点代价太高了,起码其他正在运行的程序和已经登录的其他用户不会因为被迫从计算机中退出而感到高兴。另外,Linux也可能需要好一会时间才能从一个强制的重新自检中重新启动,而且,对于正在修改的文件,也存在内容丢失的危险---更为严重的是,还有可能使您的系统不能够正常的启动。用户几乎总可以无需重新启动计算机就除去那些不服从的程序。在本章中,我们要讨论关于如何确定用户拥有哪些进程以及如何终止无用进程的问题。程序和进程很相似,但它们并不是一回事。进程或多或少地是一个正在运行着的程序。假定用户正在使用OPENLOOK或Motif,屏幕上的两个窗口内都在运行vi。尽管两个窗口中运行的是相同的程序,但它们却是正在执行不同任务的不同进程(在这个例子中,它们分别编辑不同的文件)。另外,一些程序本身要使用不止一个进程。例如,终端程序cu使用了两个进程:一个进程把用户输入的内容拷贝到远程计算机,另一个进程把数据从远程计算机拷回到用户屏幕。有时还有一些“隐藏的”进程:许多程序提供了允许用户从程序内部执行任何Linux命令的手段(例如,在ed中,用户可以输入!和想要运行的命令名来执行shell命令)。除了命令进程,也还有一个shell进程,shell进程通常用来解释命令。在大多数情况下,当用户使用ps命令查看进程列表时,很容易就能知道哪个进程对应着哪个命令,因为每个进程都对应着启动它的命令。8.1管理进程ps(processstatus)是用来发现哪些进程正在运行的基本程序。ps命令的细节因Linux版本不同而有所差异。然而,主要有两种ps:系统V类型的ps和BSD类型的ps(尽管SVR4混合了许多BSD的功能,SVR4使用的却是系统V类型的ps)。第8章进程管理-189-8.1.1基本的ps命令不管使用的是哪个版本的Linux,如果只简单地运行ps,那么用户都将看到一个显示从自己终端运行的进程的列表(表8-1)(如果用户正在使用一个窗口系统,那么列出的则是从自己的窗口运行的进程)。表8-1ps命令显示的结果PIDTTYTIMECOMMAND24812ttyp00:01Csh25973ttyp00:00psPID栏给出的是进程标识符,即进程号。为了使进程互不干扰,Linux给每一个进程一个独一无二的数字作为标志符。这些数从1开始,依次增加。当进程号变得太大以至于很不方便时(大约30000左右),Linux又从1开始分配进程号并跳过那些仍然在使用的数。为了除掉一个不能退出的进程,用户需要知道它的进程号,以便告诉系统终止哪个进程。TTY栏列出了启动进程的终端名。在这个例子中,终端是ttyp0。它碰巧是0号伪终端。伪终端是当用户从一个X窗口或通过网络从一个远程系统登录时Linux所使用的终端,而不是当用户通过一个真实的终端登录时Linux所使用的终端。对我们的目的来说,不管它们是真实的还是虚拟的、或其他什么样的,所有的终端都进行同样的工作。TIME栏是计算机运行该进程已花去的分秒时间数(等待用户输入或是等待磁盘和打印机等等所花的时间不计算在内)。COMMAND栏或多或少地显示了启动该进程的命令名。如果进程是某个特定终端或伪终端上的第一个进程,相应的命令名则以一个连字符(‘-’)开头。在这个例子中,一个进程正在运行csh(Cshell),而另外一个进程正在运行ps命令。8.1.2功能更强的ps命令系统V版本的ps命令有许多任选项,虽然实际上大多数任选项根本没有什么用处。一个比较有用的任选项是-f,它产生一个“完整”列表(表8-2)。表8-2ps–ef命令的结果表UIDPIDPPIDCSTIMETTYTIMECOMMANDjohn1117643812014:06:02Ttyp30:00/usr/bin/emacsjohn11176611764014:06:05Ttyp30:00/bin/bash–ljohn11176911766014:06:15Ttyp30:00ps–fjohn1381238040Jan18Ttyp30:04-sh比起基本的ps命令的列表来,这种表中增加了几栏信息,而且其中有几栏也不太相同。UID栏,正如上面看起来的那样,列出的是用户名。PPID栏是父进程号,即启动本进程的进程号。我们已经从shell中运行了emacs,并且随后指示emacs启动另一个shell来运行一个ps命令。父进程号反映了进程间相互启动的次序。登录shell进程(进程号为3812)是emacs的双-190-第二部分Linux的单机使用亲,而emacs反过来又是shell(/bin/bash)的双亲,/bin/bash同时又是ps的双亲(我们能解释为什么没有顺序地列出这些进程,用户不必知道详细情况)。Linux系统中的所有进程都是按照基于是哪个进程启动它们的继承层次来安排的。所有进程的共同祖先是1号进程,它也被称为init。用户可以向上追溯任何进程的祖先,最终都会到达init。“请注意!我就是所谓的ps,是Bourneshell的儿子,emacs的女儿,古老尊贵的init的曾曾孙!”C栏列出的是一个关于该进程最近已经运行了多长时间的一个完全技术性的数字,不要理睬它。STIME指启动时间,即进程开始时的一日以内的时间。如果它是在超过二十四小时之前开始运行的。那么这一栏中也会显示出日期。TTY是进程正在使用的终端名。如果用户运行GUI,如X窗口、Motif或者OPENLOOK,并且用户在一个窗口中运行xterm程序(如我们这里所做的那样),那么TTY栏并不显示用户正在使用的终端,相反地,它列出连接窗口中的shell到管理在屏幕上显示该窗口的xterm(一大块无用信息)的一个“伪终端”。有时TTY栏显示一个?号,这意味着该进程是一个不使用终端的“精灵”。COMMAND栏显示出启动该进程的完整命令名,包括(在一些情况下)程序的完整路径名(标准系统程序驻留在/bin和/usr/bin中,因此在ps列表中经常可以看到它们)。如果用户已经在几台终端上或者在几个窗口中进行了登录,那么用户可能想查看自己的所有进程,而不只是在当前终端上的进程。使用ps命令可以要求查看一个指定用户的所有进程。ps–usa这条命令列出属于用户sa的所有进程。用户也可以要求查看任何用户的进程,而不只是他自己的进程。可以输入以下命令得到某个用户进程的完整列表:ps-fusa系统V的ps还有其他一些不那么有用的任选项。特别是-e任选项,它显示出整个系统中的每个进程。伯克利ps从BSD版本的ps命令得到的基本报告看起来像下面这样:PIDTTSTATTIMECOMMAND7335P4S0:00–csh(csh)7374P4R0:00psPID,TIME和COMMAND栏的含义读者已经知道了,(COMMAND栏中,如果通用的名字中含有破折号或其他的符号,那么将在括号中列出程序的真正名字)。TT栏中列出了终端名的较短形式(在这个例子中,是4号伪终端)。STAT栏列出了进程的状态,R代表进程现在正在运行,任何其他的符号都意味着进程当前没有运行,通常用户不必关心这一栏的内容,除非在有一个程序不能退出的时候,用户才可能想了解它究竟是在静止不动地等待输入(这时它的状态是I或IW),还是已经没有响应,但仍然在不停地运行(这时它的状态是R)。带-u任选项的ps命令给出一个面向用户的报告,尽管他们的用户概念与你我所想像的可能会不同:USERPID%CPU%MEMSZRSSTTSTATSTARTTIMECOMMANDjohn173750.00.9196436p4R14:590:00ps–ujohn173350.00.6196316p4S14:560:00-tcsh%CPU栏和%MEM栏列出了进程最近占用的可用中央处理器时间和系统内存的百分比(这些数字通常都接近于0)。RSS即驻留集的大小(ResidentSetSize),是关于进程当前正在第8章进程管理-191-使用多大内存的一个度量,其单位是千字节(简写为K)。例如,ps命令正在占用436K字节内存(当想到过去整个Unix系统只占用64K字节时,这就相当惊人了)。START栏列出了进程开始执行时一日以内的时间。如下面的例子所示,用户可以用-t任选项要求列出某个特定终端上的进程:ps-tp4使用-t任选项时,用户必须输入与ps所使用的完全相同的两个字符的终端缩写。试一试出现在ps列表的TT栏中的两个字符缩写。BSD版本的ps命令还有许多其他的无用的任选项,包括-l任选项,它给出一个长的技术性列表,-a任选项显示所有进程(不只是用户本人的进程),-x任选项显示没有使用终端的进程。然而没有提供查看属于某个特定用户的所有进程的任选项。为了查看用户本人启动的所有进程,输入下面的命令:ps–aux|grepsa用自己的用户名替代sa的名字。在这个命令行中,重定向ps命令的输出到grep命令,grep命令丢弃了不包含用户本人用户名的所有行。8.1.3子进程与父进程在父进程创建一个子进程的时候,子进程从它的父进程继承了许多特征,如用户名、终端和当前目录(这一点很重要)。另一方面,子进程可以对这些信息中的许多内容进行修改。然而,继承是单向的,在子进程中所做的修改不会影响到父进程。假定用户创建了一个新进程(例如,输入bash命令启动一个新的shell作为第二个进程),然后转到非当前正在使用的另外某个目录,例如,输入cd/tmp转到/tmp目录,接着输入pwd命令以确定用户是在/tmp目录中。输入exit退出新的shell进程,再在原来的shell中输入pwd命令,可以确定确实回到了初始目录。这个例子证实了cd不可能是一个在自己的进程内执行的正常命令。因为如果它是的话,那么新目录将只与那个进程有关。一旦那个进程结束,用户将返回shell。不同shell的开发者都采用了技术上称之为“克鲁其(kludge)”的方法(有些效果,但并不能从根本上解决问题的某种方案)来巧妙地处理这一问题。这个“克鲁其”特别地搜索cd命令,并在shell内部自己处理cd命令。出于相同的原因,exit和logout命令也是在shell内部处理的。用户可能碰上这类问题,这里是一个例子:如果用户建立了一个含有一条cd命令的shell文件(参见第7章),那么这条cd命令将只影响该文件中的后续命令,在shell文件结束运行之后,用户会发现自己又回到了原来的目录,就好象cd动作从来没有发生过一样。尽管可以写出一个确实改变目录的shell文件,然而由于这样做相当复杂,所以甚至连专家们都对这个任务避之不及。-192-第二部分Linux的单机使用8.2终止进程假定用户正在工作,处理着自己的事务,这时却发现有一个程序就是不能停止。那么好,有办法让它停下来。首先,在这里讨论一下终止进程的通常方法,然后再介绍一些更强有力的手段。8.2.1终止进程的多种方法终止一个进程的通常做法是按中断字符,中断字符通常是Ctrl-C,有时也可能是Del或Delete。在许多情况下,程序会不加反抗地放弃执行,用户最后返回到shell。然而,也有一些时候,程序会自己处理Ctrl-C键。例如,如果用户使用的是ed编辑器,按Ctrl-C键,ed将返回到命令方式,而不是放弃ed用户所做的工作退出编辑。为了退出ed,
本文标题:第8章进程
链接地址:https://www.777doc.com/doc-2199425 .html