1.进程的概念
进程(Process)是一个程序在其自身的虚拟地址空间中的一次执行活动。之所以要创建进程,就是为了使多个程序可以并发地执行,从而提高系统的资源利用率和吞吐量。
进程和程序的概念不同,下面是对这两个概念的比较。
●程序只是一个静态的指令集合;而进程是一个程序的动态执行过程,具有生命期,是动态地产生和消亡的。
●进程是资源申请、调度和独立运行的单位,因此使用系统中的运行资源;而程序不能申请系统资源,不能被系统调度,也不能作为独立运行的单位,因此不占用系统的运行资源。
●程序和进程无一一对应的关系。一方面一个程序可以由多个进程所共用,即一个程序在运行过程中可以产生多个进程;另一方面,一个进程在生命期内可以顺序地执行若干个程序。
Linux操作系统是多任务的,如果一个应用程序需要几个进程并发地协调运行来完成相关工作,系统会安排这些进程并发运行,同时完成对这些进程的调度和管理任务,包括CPU、内存、存储器等系统资源的分配。
2.Linux中的进程
在Linux系统中总是有很多进程同时在运行,每一个进程都有一个识别号,叫作PID(Process ID),用于与其他进程区别。系统启动后的第一个进程是systemd,其PID是1。systemd是唯一一个由系统内核直接运行的进程。新的进程可以用系统调用fork来产生,就是从一个已经存在的进程中派生出一个新进程,旧的进程是新产生的进程的父进程,新进程是产生它的进程的子进程。
当系统启动以后,systemd进程会创建login进程等待用户登录系统,login进程是systemd进程的子进程。当用户登录系统后,login进程就会为用户启动Shell进程,Shell进程就是login进程的子进程,而此后用户运行的进程都是由Shell衍生出来的。
在多用户多任务的Linux系统里,每个进程都与运行的用户和组相关联。除了进程识别号(PID)外,在进程控制块(PCB)中每个进程还有另外4个与用户和组相关的识别号。它们是实际用户识别号(real user ID,RUID)、实际组识别号(real group ID,RGID)、有效用户识别号(effect user ID,EUID)和有效组识别号(effect group ID,EGID)。
RUID和RGID的作用是识别正在运行此进程的用户和组。一个进程的RUID和RGID就是运行此进程的用户的UID和GID。
EUID和EGID的作用是确定一个进程对其访问的文件的权限和优先权。除非产生进程的程序被设置了SUID和SGID权限之外,一般,EUID、EGID与RUID、RGID相同。若程序被设置了SUID或SGID权限,则此进程相应的EUID和EGID,将与运行此进程文件的所属用户的UID或所属组的GID相同。例如,一个可执行文件/usr/bin/passwd,其所属用户是root(UID为0),此文件被设置了SUID权限。当一个UID为500、GID为501的用户执行此命令时,产生的进程的RUID和RGID分别是500和501,而其EUID是0,EGID是501。
尽管看上去有些烦琐,但是所有这些设计都是为了在一个多用户、多任务的操作系统中,所有用户的工作都能够安全可靠地进行,而这也是Linux操作系统的优势所在。
3.进程的类型
可以将运行在Linux系统中的进程分为3种不同的类型。
●交互进程:由一个Shell启动的进程。交互进程既可以在前台运行,也可以在后台运行。
●批处理进程:不与特定的终端相关联,提交到等待队列中顺序执行的进程。
●守护进程:在Linux启动时初始化,需要时运行于后台的进程。
以上3种进程有各自的特点、作用和使用场合。
4.进程的启动方式
启动一个进程有两个主要途径:手工启动和调度启动。
(1)手工启动
由用户输入命令,直接启动一个进程便是手工启动进程。手工启动进程又可以分为前台启动和后台启动。
前台启动:手工启动一个进程的最常用方式。一般地,用户输入一个命令“ls-l”,这就已经启动了一个进程,而且是一个前台的进程。
后台启动:直接从后台手工启动一个进程用得比较少一些,除非是该进程甚为耗时,且用户也不急需要结果的时候。假设用户要启动一个需要长时间运行的格式化文本文件的进程,为了不使整个Shell在耗时进程的运行过程中都处于“瘫痪”状态,从后台启动这个进程是明智的选择。
在后台启动一个进程,可以在命令行后使用&命令,例如:
(2)调度启动
这种启动方式是事先进行设置,根据用户要求让进程自行启动运行,参见6.2节。
1.获取进程信息的命令
通过命令可以查看进程状态,获取有关进程的相关信息。例如:
●显示哪些进程正在执行和执行的状态。
●进程是否结束、进程有没有僵死。
●哪些进程占用了过多的系统资源等。
表3-20中列出了常用的获取进程信息的命令。
表3-20 常用的获取进程信息的命令
2.ps命令
在Linux中,可使用ps命令对进程进行查看。ps是一个功能非常强大的进程查看命令。使用该命令使用户可以确定有哪些进程正在执行和执行的状态、进程是否结束、进程有没有僵死、哪些进程占用了过多的系统资源等。总之,大部分信息都可以通过运行ps命令来获得。下面介绍ps命令的格式和常用选项。ps命令的格式如下:
由于ps命令的功能相当强大,所以该命令有大量的选项参数,这里只介绍几个最常用的选项,如表3-21所示。
表3-21 ps命令的常用选项
表3-22中列出了ps命令输出的重要信息的含义。
表3-22 ps命令输出的重要信息的含义
其中,在进程状态(STAT)一栏中表示状态的字符含义如表3-23所示。
表3-23 进程状态的字符含义
3.进程显示命令举例
下面给出一些显示进程信息的例子。
操作步骤3.13 显示进程信息的例子
提示
不加“-l”参数的pgrep命令的输出仅是符合条件进程的PID。若要显示这些进程更详细的信息,还需要使用如下形式之一:
●$ps-fp$(pgrep-d,XXXXX)。
●$pgrep-x XXXXX|xargs ps-fp。
1.为什么要杀死进程
在系统运行期间,若发生了如下情况,就需要将这些进程杀死。
●进程占用了过多的CPU时间。
●进程锁住了一个终端,使其他前台进程无法运行。
●进程运行时间过长,但没有预期效果或无法正常退出。
●进程产生了过多的到屏幕或磁盘文件的输出。
2.进程信号
进程信号是在软件层次上对中断机制的一种模拟,在原理上,一个进程收到一个信号与处理器收到一个中断请求可以说是一样的。进程信号是最基本的进程间通信方式:可以在进程之间直接发送,而不需要用户界面;可以在Shell中通过kill命令发送给进程。
Linux对每种进程信号都规定了默认关联动作。可以使用如下命令查看可用的进程信号及其详细信息。
表3-24中列出了一些常用进程信号的说明。
表3-24 常用进程信号说明
3.可以发送进程信号的命令
表3-25中列出了常用的发送进程信号的命令。
表3-25 常用的发送进程信号的命令
可以使用上述命令为进程发送SIGTERM(15)或SIGKILL(9)信号杀死进程。
4.杀死进程举例
下面给出一些杀死进程的例子。
操作步骤3.14 杀死进程的例子
提示
1.killall使用进程名称而不是PID,所以所有的同名进程都将被杀死。
2.pkill/pgrep在杀死进程时应使用精确匹配(-x),以免殃及池鱼。
1.作业控制的含义
作业控制是指控制当前正在运行的进程的行为,也称为进程控制。作业控制是Shell的一个特性,使用户能在多个独立进程间进行切换。例如,用户可以挂起一个正在运行的进程,稍后再恢复其运行。bash记录所有启动的进程并保持对所有已启动的进程的跟踪,在每一个正在运行的进程生命期内的任何时候,用户可以任意地挂起进程或重新启动进程恢复运行。
例如,当用户使用vi编辑一个文本文件,并需要中止编辑做其他事情时,利用作业控制,可以让编辑器暂时挂起,返回Shell提示符开始做其他的事情。其他事情做完以后,用户可以重新启动挂起的编辑器,返回到刚才中止的地方,就像用户从来没有离开编辑器一样。这只是一个例子,作业控制还有许多实际的用途。
2.实施作业控制的常用命令
表3-26中列出了作业控制的常用命令或操作快捷键。
表3-26 作业控制的常用命令或操作快捷键
这些命令常用于用户需要在后台运行却意外地放到了前台启动运行的时候。当一个命令在前台被启动运行时,会禁止用户与Shell的交互,直到该命令结束。由于大多数命令的执行都能很快完成,所以一般情况下不会有什么问题。但如果要运行的命令要花费很长时间的话,通常会把它放到后台,以便能在前台继续输入其他命令。此时,上面的命令就会派上用场了。
3.作业控制举例
下面给出一个例子说明作业控制命令的使用。
操作步骤3.15 作业控制命令的使用
提示
Windows用户通常有随时按快捷键〈Ctrl+S〉进行保存的习惯,但在Linux的终端上按快捷键〈Ctrl+S〉表示挂起终端,要解除挂起需按快捷键〈Ctrl+Q〉。