【一】进程概述
进程是正在运行的程序的实例,代表一个具有独立功能的程序及其数据集的一次执行。它是操作系统动态执行的基本单元,在传统操作系统中,进程既是资源分配的基本单位,也是执行的基本单位。
一个程序可以创建多个进程,进程是由内核定义的抽象实体,并为其分配执行所需的系统资源。从内核角度看,进程由用户内存空间和一系列内核数据结构组成。用户内存空间包含程序代码和所使用的变量,而内核数据结构则用于维护进程的状态信息。进程在内核数据结构中的记录包括各种标识号(IDS)、虚拟内存表、打开文件的描述符表、信号处理信息、资源使用及限制、当前工作目录等大量信息。进程的状态分为五种,如表所示:
状态 | 说明 |
运行态 | 进程占用处理器,正在运行 |
就绪态 | 进程具备运行条件,等待系统分配处理器 |
阻塞态 | 进程不具备运行条件,等待某事件完成后再运行 |
新建态 | 进程刚被创建,尚未进入就绪队列 |
终止态 | 进程完成任务或出现不可恢复错误而终止 |
【二】进程的类型
在Linux中,进程一般分为交互进程、批处理进程和监控进程三类,如表所示:
进程类型名称 | 说明 |
交互进程 | 与用户交互频繁,需要等待键盘和鼠标操作。接收输入后需快速响应,否则用户会感到系统迟钝。 |
批处理进程 | 不需与用户交互,常在后台运行,调度程序常对其怠慢。 |
监控进程 | 独立于控制终端,周期性执行任务或等待事件发生。大多数Linux服务器由守护进程实现,如ftp服务器。 |
交互进程是由Shell启动,可以在前台或后台运行。批处理进程与终端无关,是一组程序序列。监控进程又称守护进程,在后台运行,不受终端控制,用于执行特定系统任务。
【三】查看进程
在Linux系统下查看进程的常用命令有三个,各自功能不同,适用于不同场景。以下是详细介绍。
①ps 命令
ps命令是最常用的进程查看命令。通过执行ps命令可以查看当前运行的进程状态及资源占用情况,但ps命令显示的是瞬时状态,不是连续动态的。
ps命令选项参数值有6个,如表所示:
选项 | 说明 |
-a | 显示一个终端的所有进程,除了会话引线 |
-u | 显示当前用户进程及内存的使用情况 |
-x | 显示没有控制终端的进程 |
-l | 长格式显示详细信息 |
-e | 显示所有进程 |
-f | 格式显示,包括命令行 |
执行ps命令后,会显示进程列表,如图所示:
进程列表字段说明如表所示:
字段 | 说明 |
USER | 产生该进程的用户 |
PID | 进程ID |
%CPU | 进程占用CPU资源的百分比 |
%MEM | 进程占用物理内存的百分比 |
VSZ | 进程占用虚拟内存的大小(KB) |
RSS | 进程占用实际物理内存的大小(KB) |
TTY | 进程运行的终端 |
STAT | 进程状态 |
START | 进程的启动时间 |
TIME | 进程占用CPU的运算时间 |
COMMAND | 产生此进程的命令名 |
STAT——进程状态取值说明,如表所示:
字段 | 说明 |
D | 不可唤醒的睡眠状态,通常用于I/O操作 |
R | 正在运行 |
S | 可被唤醒的睡眠状态 |
T | 停止状态,可能是暂停或除错状态 |
W | 内存交换状态 |
X | 崩溃的进程 |
Z | 僵尸进程 |
< | 高优先级 |
N | 低优先级 |
L | 被锁定在内存中 |
s | 包含子进程 |
l | 多线程 |
+ | 位于后台 |
【例】列出所有在内存中运行的进程。
如果系统目前有许多正在运行的进程,可以用 more 命令逐步查看。在命令行模式下输入 "ps aux | more" 命令,具体操作如图所示:
②top 命令
top命令以动态方式查看进程状态,可通过按键不断刷新状态,独占前台直到终止。top命令提供实时CPU状态监控,可按CPU使用率、内存使用率、执行时间排序。
该语法中,top命令选项参数值有八个,如表所示:
选项 | 说明 |
-d | 改变显示的更新速度 |
-q | 无延迟显示速度 |
-c | 切换显示模式,显示执行档名称或完整路径 |
-S | 累积模式,累积已完成或消失的子进程CPU时间 |
-s | 安全模式,取消交互式指令 |
-i | 不显示任何闲置或无用的进程 |
-n | 更新次数,完成后退出top |
-b | 批次模式 |
【例】显示系统进程并每3秒更新一次信息。
在命令行模式中,通过输入 top 命令可以显示进程信息,并按照设定的秒数更新信息。通过设置“-d”参数可以实现这个功能,输入的完整命令为“top -d 3”,要退出 top 进程查看,可以按 Ctrl+C 键,具体操作如图所示:
③pstree 命令
pstree命令以树形结构显示程序和进程之间的关系,适用于查看进程树之间的关系。
该语法中,pstree命令选项参数值有五个,如表所示:
选项 | 说明 |
-a | 显示启动每个进程的完整指令,包括路径和参数 |
-c | 不使用精简法显示进程信息 |
-p | 显示进程的PID |
-u | 显示进程对应的用户名称 |
-n | 根据进程PID号排序输出,默认以程序名排序 |
【例】显示进程树并显示进程号。
在命令行模式中,输入“pstree -p”命令,其中“-p”参数用于显示进程的PID值。结果会以树状结构展示,可以清晰地看到进程之间的父子关系。具体操作如图所示:
【四】定时调度任务进程
crond是Linux下的守护进程,用于周期性地执行任务或等待事件,类似Windows的计划任务。操作系统安装后默认安装并自动启动crond进程。crond每分钟检查是否有任务执行,如果有则自动执行。
crontab是Linux系统的定时执行工具,可以在无人干预下运行作业,通过crond进程提供服务,crond每分钟检查任务执行情况。
crontab配置文件所在位置如表所示:
路径 | 说明 |
/var/spool/cron/ | 存放用户的crontab任务,每个任务以登录名命名 |
/etc/crontab | 存放系统管理员创建并维护的crontab任务 |
/etc/cron.d/ | 存放任何要执行的crontab任务 |
crontab配置文件如图所示:
crontab时间参数说明如表所示:
时间 | 说明 |
minute | 一小时中的第几分钟(0~59) |
hour | 一天中的第几小时(0~23) |
day of month | 一个月中的第几天(1~31) |
month | 一年中的第几个月(1~12) |
day of week | 一周中的周几(1~7) |
crontab中的特殊字符,如表所示:
特殊字符 | 说明 |
* | 代表所有可能的值。例如,若month字段为星号,则表示在满足其他字段的制约条件下每个月都执行该命令。 |
, | 用逗号隔开的值指定一个列表范围,例如,“1,2,5,7,8,9”。 |
- | 表示一个整数范围,例如,“2-6”表示“2,3,4,5,6”。 |
*/n | 指定时间的间隔频率,例如,“0-23/2”表示每两小时执行一次。 |
该语法中,选项参数值有3个,如表所示:
选项 | 说明 |
-e | 使用文字编辑器来设定时程表,默认的文字编辑器是vi。 |
-r | 删除目前的时程表。 |
-l | 列出目前的时程表。 |
【例】:设置定时任务,每隔一分钟执行一次。
每隔一分钟将root用户主目录下的文件列表保存到filelist文件中。实现这个功能需要在命令行模式下输入“crontab -e”命令,按Enter键进入vi编辑脚本,输入设置的脚本,保存并退出即可。具体操作如图所示:
【五】进程的优先级
当CPU处理数据时,并不是把一个进程的数据运算完成后再处理下一个进程的数据。如果当前系统中有3个应用进程,它们的进程优先级相同,分别是进程A、进程B、进程C,CPU会先处理进程A,再处理进程B,然后处理进程C,之后再处理进程A,如此循环进行,直到进程任务结束。如果设置了优先级,CPU会优先处理优先级高的进程。在进程中,表示优先级的参数主要有两个:Priority和Nice。Priority的缩写是PRI,Nice的缩写是NI。这两个参数的数值越小,代表该进程越优先被CPU处理。PRI值用户不能直接修改,由Linux系统内核动态调整;而NI值可以由用户进行修改,从而间接调整进程的优先级。PRI与NI的关系可以表示为:PRI(最终值) = PRI(原始值) + NI
修改NI值时需要注意几个问题。NI值的可修改范围是-20到19,但普通用户只能调整0到19之间的值,并且只能调整自己的进程,且只能调高NI值,不能降低。只有root用户才能设置负值,并且可以调整任何用户的进程。
【六】进程调度
为什么在Linux系统下要进行进程调度?这里的调度是什么意思呢?所有程序的运行都需要CPU的处理,面对众多的进程执行请求,CPU如何响应及管理的方式就是调度,或对CPU进行时间分割管理的具体做法称为调度。
最早的计算机没有进程调度功能,程序只能一次运行一个,一个进程结束后才能运行下一个进程。即便没有同时运行多个进程的需求,如果程序运行过程中需要等待IO,CPU只能空转,十分浪费资源。基于这个问题,早期研发人员推出了协作式多任务。当程序需要IO而阻塞时,系统会调度执行其他进程。但这种方式存在问题:每个进程运行的时间片长短不确定,而且非常随机。如果一个进程一直在做运算,没有IO操作,它会一直占用CPU资源。当时解决这个问题的办法是靠道德约束,因为使用者是少数科研机构和政府机关人员,大家都认识。
随着计算机的普及,使用者从专业人员变成大众,协作式多任务已行不通,需要强制执行多任务,也就是抢占式多任务。抢占式多任务使每个进程相对公平地平分CPU时间。如果一个进程运行时间过长,会被强制性地调度出去。有了抢占式多任务,我们在宏观上可以同时运行多个进程,并且它们会一起向前运行,不会出现某个进程被“饿死”的情况,这样运行程序的体验就非常好。
【七】 后台运行进程
在Linux系统下,执行某个耗时任务时会长时间占用终端,例如上传较大文件,这会影响其他程序或命令的运行。可以把这种耗时命令发送到后台执行,从而释放终端继续执行其他命令。把程序发送到后台非常简单,只需要在命令后加上“&”符号。
如果已经运行一个程序,又想把它发送到后台运行,可以先按Ctrl+Z键暂停正在运行的进程,然后使用bg命令将进程发送到后台继续运行。
命令语法如下:
正在运行的程序
^Z
bg
要查看正在运行的后台进程,可以使用jobs命令。此命令会显示后台运行的进程,其中序号后跟“+-”符号,“+”表示最后执行的进程,“-”符号表示倒数第二执行的进程。
【八】终止进程
在运行Linux系统过程中,可能会有进程出现僵死状态,占用端口资源或其他原因无法重启进程,这时需要通过终止进程的方式来结束该进程。常用的结束进程方法有kill和killall命令。kill用于结束指定进程,killall用于结束同名进程。使用kill命令结束进程时,需要与ps命令配合使用,因为需要先确认进程号PID值。如果遇到僵死进程,直接执行kill命令可能会失败,通常使用“-9”参数强制结束进程。
该语法中,选项参数值有5个,如表所示:
选项 | 说明 |
-l | 如果不加信号编号参数,则使用“-l”参数列出全部的信号名称。 |
-a | 当处理当前进程时,不限制命令名和进程号的对应关系。 |
-p | 指定kill命令只打印相关进程的进程号,而不发送任何信号。 |
-s | 指定发送信号。 |
-u | 指定用户。 |
kill命令一共有七种信号,可以无条件终止进程,如表所示:
数字 | 说明 |
1 | 终端断线。 |
2 | 中断(Ctrl+C)。 |
3 | 退出(Ctrl+\)。 |
9 | 强制终止。 |
15 | 终止。 |
18 | 继续。 |
19 | 暂停。 |