进程概述
进程是一个二进制程序的执行过程,在Linux操作系统中,向命令行输入一条命令按下回车,便会有一一个进程被启动。
进程的处理机制
从计算机用户的角度看,一台计算机可同时运行多个进程,但实际上,一个单核的CPU同一时刻只能处理一 个进程,用户之所以会任务同时有多个进程在运行,是因为计算机系统采用了“多道程序设计”技术。
所谓多道程序设计,是指计算机允许多个相互独立的程序同时进入内存,在内刻的管理控制之下,相互之间穿插运行。多道程序设计必须有硬件基础作为保障。
CPU处理进程的示意图如下所示。
进程属性
进程对CPU的使用权是由内核分配的,内核必须知道内存中有多少个进程,并且知道此时正在使用CPU的进程,这就要求内核必须能够区分进程,并可获取进程的相关属性。
进程的属性保存在一个被称为进程控制块 ( Process Contral Block ,简称PCB )的结构体中, 内核为每个进程维护了一个进程控制块,用于管理相应进程的属性信息。 PCB的本质是一个task struct结构体,其中包括进程控制符( Process ldentifier , PID )、 进程组、进程环境、进程的运行状态等。
Linux内核通过管理PCB,来调度进程。
标识符
Linux系统中进程的标识符主要有:进程标识符、父进程标识符、用户标识符和组标识符。
进程标识符:简称pid,是进程的唯一标识。 父进程标识符:简称ppid,标识该进程的父进程,即创建进程的进程所对应的pid 用户标识符:简称uid,标识创建该进程的用户。此外euid标识有效用户标识符。
组标识符:简称gid,标识创建进程用户的所属组。Euid对应的组标识符即egid
Linux中提供了获取进程标识符的接口,不同标识符对应的函数如表所示。
标识符 | 函数接口 |
pid / ppid | pid_tgetpid(void); / pid_tgetppid(void); |
uid / euid | uid_ tgetuid(void); / uid_tgeteuid(void); |
gid / egid | gid_tgetgid(void);gid_tgetegid(void); |
进程状态
通常进程的状态被划分为五种:初始态、就绪态、运行态、睡眠态和终止态。初始态一般不进行讨论,因为当初始化完成后,进程会立刻转化为就绪态。
就绪态:处于就绪态( Ready )的进程,所需的其它资源已分配到位,此时只等待cpu,当可以使用cpu时,进程会立刻变为运行态。
运行态:进程处于运行态( Execting )时会占用cpu ),处于此状态的进程的数目必定小于等于处理器的数目,即每个cpu_上至多能运 行一个进程。
睡眠态:处于睡眠态( Sleeping )的进程会因某种原因而暂时不能占有cpu。睡眠态分为不可中断的睡眠和可中断的睡眠。
终止态:处于终止态的进程已运行完毕,此时进程不会被调度,也不会再占用CPU。
进程通常会在就绪态、运行态、睡眠态和终止态这四种状态中换换,这四种状态间可能发生的转换如图所示。
寄存器信息
cpu中寄存器的数量是有限的,若进程p1的时间片结束,进程p2将获得cpu, cpu中的寄存器应给进程p2使用。但进程p1可能尚未执行结束,在之后的某个时间片,进程p1需重新获得cpu的使用权。因此在进程切换时,应先保存寄存器中存储的进程p1的数据,以便进程p1再次使用cpu时,能从中断的位置继续向下执行。
页表指针
当程序运行时,系统会为程序开辟一段4G大小的虚拟内存,其中0~3G的虚拟地址用于英语存放程序的代码段、数据段等信息,当虚拟内存与物理内存相映射时,各个虚拟内存中地址相同的数据,会被MMU(Memory Management Unit,内存管理单元)映射到内存中不同的物理地址,为保证内核能根据进程中的虚拟地址在物理磁盘中找到进程中所需的数据,PCB应存储虚拟地址与物理地址的对应关系。
Linux系统采用分页存储的方式管理内存:在进程装载入内存之前,系统将用户进程的逻辑地址空间分成若干个大小相等的片,这些片称为页面或页,并为各个页编号;相应地,内存空间也使用相同的方式,划分为与逻辑地址页面大小相同的块并进行编号。之后当为进程分配内存时,以块为单位,将进程中的若干个页装入多个可以不相邻的物理块中。此时逻辑地址与物理地址间应有个对应关系。Linux操作系统中使用页表来存储这个对应关系,这个页表的实质是一个结构体。
每个进程的pcb中都有一个指向页表的指针,进程、页表与内存之间的映射关系如图所示。
进程管理命令
进程id既能方便系统对进程的管理和调度,也方便用户对进程的管理。Linux系统中提供了许多进程管理命令,掌握这些命令,能帮助用户更好地管理进程,以及进程所需的相关资源。
PS:是“Process Status”的缩写。在命令行输入“ps”后回车就能查看当前系统中正在运行的进程。ps的命令格式如下:
ps [选项] [参数]
执行ps命令后终端打印的信息如图:
ps命令可以与一些选项搭配,实现更丰富的功能。它的选项有两种风格:SysV和BSD。SysV风格的选项需要与“-”,一起使用,BSD风格的选项可以直接使用。
选项 | 说明 |
a | 显示当前终端机下的所有进程,包括其它用户启动的进程 |
u | 以用户的形式,显示系统中的进程 |
x | 忽视终端机,显示所有进程 |
e | 显示每个进程使用的环境变量 |
r | 只列出当前终端机中正在执行的进程 |
选项 | 说明 |
-a | 显示所有终端机中除阶段作业领导之外的进程 |
-e | 显示所有进程 |
-f | 除默认显示外,显示UID、PPID、C、STIME项 |
-o | 指定显示哪些字段,字段名可以使用长格式,也可以使用“%字符”的短格式指定,多个字段名使用逗号分割 |
-l | 使用详细的格式显示进程信息,等同于BSD风格的选项l |
top:ps命令执行后,会显示执行命令那一刻系统中进程的相关信息,若想使信息动态地显示,可以使用top命令。
top的命令格式: top [选项]
top命令可以实时观察系统的整体运行情况,默认时间间隔为3秒,即每3秒更新一次页面,类似Windows系统中的任务管理器,是一个很实用的系统性能监测工具。
在终端执行top命令后的界面如下:
运行top命令后可通过热键对显示的信息进行操作,常用的热键及其对应的功能如表所示。
热键 | 说明 |
l | 控制是否显示平均负载和启动时间(第1行) |
t | 控制是否显示进程统计信息和cpu状态信息(第2、3行) |
m | 控制是否显示内存信息(第4、5行) |
M | 根据常驻内存集RES大小为进程排序 |
P | 根据%CPU为进程排序 |
T | 根据TIME+为进程排序 |
r | 重置一个进程的优先级 |
i | 忽略闲置和僵死的进程 |
k | 终止一个进程 |
pstree:命令以树状图的形式显示系统中的进程,可以直接观察到进程之间的派生关系。
pstree命令的格: pstree [选项]
pstree命令中的常用选项如表所示
选项 | 说明 |
-a | 显示每个进程的完整命令(包括路径、参数等) |
-c | 不使用精简标识法 |
-h | 列出树状图,特别标明当前正在执行的进程 |
-u | 显示用户名称 |
-n | 使用程序识别码排序(默认以程序名称排序) |
pgrep:命令根据进程名从进程队列中查找进程,查找成功后默认显示进程的pid。pgrep命令的格式如下:
pgrep [选项] [参数]
Linux系统中可能存在多个同名的进程,pgrep命令可以通过选项缩小搜索范围,其常用选项如表所示。
选项 | 说明 |
-o | 仅显示同名进程中pid最小的进程 |
-n | 仅显示同名进程中pid最大的进程 |
-p | 指定进程父进程的pid |
-t | 指定开启进程的终端 |
-u | 指定进程的有效用户id |
nice:命令用于设置Linux系统中进程的nice值,该命令的格式如下:
nice [选项] [参数]
nice选项常用的选项为-n,n表示优先级,是一个整数。
bg和fg:Linux系统中可以使用bg命令和fg命令,使进程在前台和后台之间进行切换。
bg命令的作用是,将进程放入后台运行,使前台可以执行其它任务。其命令格式如下:
bg 参数
fg命令的作用与bg相反,是将后台的进程调往前台。其命令格式如下:
fg 作业号
jobs:使用jobs命令可以查看Linux系统中的作业列表及作业状态,进程中的作业也有编号,编号从1开始。Linux系统中作业从用户角度进行编号,进程从系统管理员的角度进行编号。jobs命令的语法格式如下:
jobs [选项] [参数]
当选项和参数缺省时,默认显示作业编号、作业状态和启动作业的命令。jobs命令的常用选项如表所示:
选项 | 说明 |
-l | 显示进程号 |
-p | 仅显示作业对应的进程号 |
-n | 显示作业状态的变化 |
-r | 仅显示运行状态的任务 |
-s | 仅显示停止状态的任务 |
kill :kill命令用来终止正在运行的进程,它的工作原理是发送某个信号到指定进程,以终止该进程。kill的命令格式如下:
kill [选项] [参数]