Linux下的进程管理(附加详细实验案例)
一、进程与线程的概念与区别
1.进程的概念
- 程序是人类按照机器能够读懂的语言所写的代码(组成:数据+逻辑)
- 进程是程序在操作系统中的一次执行过程,是操作系统进行资源分配和调度的一个基本单位。它是一个程序在一个数据集合上运行过程的描述,当一个程序被加载到内存中运行时,便是一个进程。
- 进程是计算机通过人为调用开启程序之后,把硬盘当中的代码复制到内存中,然后让CPU通过代码调用它需要处理的数据,再进行相应地处理,并且把处理过的的数据保存到硬盘的一个过程。
- 进程对CPU的占用决定了系统速度的快慢,占用时间越长,CPU计算的时间越差,系统越慢。
2.线程的概念
- 线程是进程中的一个执行单元、一个实体,是CPU调度和分派的基本单位,是比进程更小的能独立运行的基本单位。一个进程可以包含多个线程。
- 线程基本上不拥有系统资源,只拥有一点在运行中必不可少的资源(如程序计数器,一组寄存器和栈),但它可与同属一个进程的其他的线程共享进程所拥有的全部资源。
3.进程与线程的区别
进程 | 线程 | |
拥有资源 | 资源相互独立,每个进程拥有独立的地址空间(代码、数据段、堆栈段) | 共享大部分资源,同一进程内的线程共享进程的地址空间和资源,如内存、文件句柄和其他资源(除了线程栈) |
通信方式 | 复杂(进程间通信(IPC)需要特殊的机制,如管道、信号、共享内存、消息队列等) | 简单(线程共享进程资源,可以直接读写进程数据段来进行通信,如全局变量) |
独立性 | 独立运行(一个进程崩溃不会直接影响到其他进程) | 相互依赖(同一进程下的一个线程崩溃可能会影响到其他线程) |
上下文切换 | 开销较大(需要切换虚拟地址空间、页表等资源) | 开销较小(主要切换栈指针、程序计数器、寄存器等) |
二、进程的状态
在Linux内核里,进程有时候也叫做任务。
R:运行状态(running,ready),并不意味着进程一定在运行中,它表明进程要么是在运行中,要么在运行队列里。
S:睡眠状态(sleeping)(阻塞状态),进程在等待某些事件(如输入、输出、信号等)完成,这里的睡眠有时候也叫做可中断睡眠。
T:停止状态(stopped),可以通过发送 SIGSTOP 信号给进程来停止(T)进程。这个被暂停的进程可以通过发送 SIGCONT 信号让进程继续运行。
D:磁盘休眠状态(Disk sleep),常是由于等待某些资源(如磁盘 I/O)而进入此状态。此时进程无法被唤醒,直到等待的资源可用,有时候也叫不可中断睡眠状态(uninterruptible sleep)。
X:死亡状态(dead),这个状态只是一个返回状态,你不会在任务列表里看到这个状态。
Z:僵尸状态(Zombies),当进程退出并且父进程没有读取到子进程退出的返回代码时,就会产生僵死(尸)进程(使用wait()或waitpid()等函数来获取最终状态)
三、进程查看的方法
1.在图形中查看进程
进程类似于 Windows 的任务管理器
命令:gnome-system-monitor(打开图形中的进程管理工具)
选择活跃的进程进行查看,可知目前CPU正在处理 gnome-system-monitor,Memory(占用内存)为21.2MB。
2.常用进程查看命令的使用
1)ps 命令 (process status ,即进程状态)
- ps命令的三种执行风格:UNIX(短参数)、BSD(短参数)、GNU(长参数)
- 带 - 是UNIX风格,不带 - 的是BSD操作系统(UNIX的一种)
ps 所显示的所有参数说明:
PID:进程的ID,每个进程在系统中都有一个唯一的PID
TTY:进程所用的终端、所用的字符设备,如果进程不少从终端启动或与终端无关,TTY会显示一个问号(?)
STAT:进程状态
TIME:进程占用CPU的时间,表示进程使用CPU资源的百分比
COMMAND:启动进程命令的名称
USER:进程所有人
%CPU:进程使用CPU的用量
%MEM:进程所用到的内存用量
VSZ:进程使用的虚拟内存大小
RSS:进程常驻内存中的数据大小
TTY:进程用到的终端
START:进程运行时长
PCPU:父级进程的CPU
PPID:父级进程的PID
ps 命令常用参数及用法:
BSD风格:
命令 | 功能 | 用法 |
a | 显示与终端相关的进程 | ps a:查看与终端相关的进程 |
x | 显示与终端无关的进程 | ps x:查看与终端无关的进程 |
u | 查看用户信息归类的方式 | ps axu:查看所有进程信息进行归类 |
f | 显示进程层级关系 | ps f:以 /_ 的形式显示进程的层级关系 |
o | 显示指定参数 | ps axo:pid,%cpu,%mem:按照输入顺序显示指定参数的进程信息 |
ps a 查看与终端相关的进程。
ps x 则查看与终端无关的进程。
ps ax 表示与终端相关和无关的进程。
ps aux 以用户的身份查看进程所有者对进程的信息来进行归类。
ps f 用 \_ 的形式显示进程阶级关系,从以下图可知,该进程是 bash 的子进程。
ps o 显示指定参数的进程,按照输入的顺序排列。
UNIX风格:
命令 | 功能 | 用法 |
-e | 显示所有进程 | ps -e:查看所有进程信息,相当于ps -A 和 ps ax |
-f | 显示信息完整的格式 | ps -f:查看当前用户进程的完整信息 |
-H | 显示进程的层级结构 | ps -H:以缩进的形式显示进程的层级结构 |
-o | 显示指定参数 | ps -eo pid,%cpu,%mem:按照输入顺序显示指定参数的进程信息 |
--sort= | 显示以指定参数的排序结果, 参数前加 - 表示降序 | ps -eo pid,pcup --sort=pid:按 pid 正序排列显示所有进程 ps -eo pid,pcup --sort=-pid:按 pid 降序排列显示所有进程 |
ps -e 显示所有进程,与 ps ax 相同。查看 ps -e 和 ps ax 的数量大概检验它们显示的进程是否相同。
ps -ef 显示所有进程的完整信息。一般情况下在显示进程的最后一行中,进程名称为 ps ,而 ps -ef 则可显示完整的进程名称。
ps -H 用缩进的形式显示进程的层级结构,与 ps f 意思相同,只是形式不同(以下是对比图)。
ps -o 按照输入顺序显示指定参数的信息,相当于 ps o 。
ps --sort= 表示对进程进行排序,= 后面为排序的依据。
正序:降序:
2)pgrep 命令(即进程过滤)
Linux 中的 pgrep 命令用于根据名称、用户、组和其他标准检索正在运行的进程,显示匹配的进程ID。
pgrep 命令常用参数及用法:
参数 | 功能 | 用法 |
-u uid | 显示指定用户ID的进程 | pgrep -u 1000:查看 UID 为1000的用户的进程ID |
-U user | 显示指定用户名称的进程 | pgrep -U lxt:查看 lxt 用户的进程ID |
-l | 显示进程ID和名称 | pgrep -lu 1000:查看 UID 为1000的用户的进程ID和名称 |
-a | 显示进程的完整名称 | pgrep -laU lxt:查看 lxt 用户进程的完整名称 |
-P | 显示进程的子进程 | pgrep -P 54393:查看 |
-t tty | 显示指定终端的进程 | pgrep -t pts/1:查看再终端 pts/1 上运行的进程ID |
首先建立两个终端,都进入到 lxt 用户界面,随后再另外打开一个终端进行操作。
① -u
pgrep -u 1000 显示指定用户ID的进程,先查看 lxt 用户的 id 是什么,再用命令查看进程。
② -U
pgrep -U user 显示指定用户名称的进程,以下是查看 lxt 用户的进程。
③ -l
pgrep -l 可显示进程名称,分别在 u 和 U 前面加 l ,便可查看对应的进程名称。
④ -a
pgrep -a 可显示进程的完整名称,在 -l 下,分别在 u 和 U 前面加 a ,便可查看对应的完整进程名称。
⑤ -P
首先查看第一个终端的 lxt 的进程,并打开 vim 在后运行(Ctrl + Z 后台运行)
pgrep -P 进程 显示子进程,随后再输入 ps 命令查看 vim 的进程 id ,并在另一个终端执行 pgrep -P 54393 命令,查看到的子进程 id 与 vim 的进程 id 相同。
⑥ -t
pgrep -t pts/1 显示 pts/1 的进程 id ,从下图可知终端的进程与 bash 的 PID 相同。
3)pidof 命令
pidof 进程名称:可直接查看 vim 的 PID 为 50185,不用像第一个命令需要输入的内容多。查出 vim 的 PID 后便可处理 vim 进程,以下是强制退出。
4)top 命令
进行动态监控,默认情况下 3 秒变一次。
top 中的内容分析:
① 系统负载:
01:19:51 | up 16:32 | 2 users | load average: 0.75, 0.53, 0.41 |
系统时间 | 运行时长 | 系统中有两个用户登陆 | 系统负载(运行时处理的速度):1min 5min 15min排队时长 |
② Task:
343 total | 1 running | 342 sleeping | 0 stopped | 0 zombie |
任务总量 | 1个正在运行 | 休眠人物数量为342 | 被暂停数量为0 | 僵死人物数量为0 |
③ %Cpu(s):
0.2 us | 0.2 sy | 0.0 ni | 99.3id | 0.0 wa | 0.1 hi | 0.0 si | 0.0 st |
用户空间 | 内核空间 | nice值调整时间 | 空闲时间 | 等待i/o时间 | 处理硬件中断时间 | 处理软件中断时间 | 被偷走的时间 (vim使用时间) |
④ MiB Mem 和 MiB Swap:
7653.6 total | 5579.7 free | 1557.6 used | 794.6 buff/cache |
1024.0 total | 1024.0 free | 0.0 used | 6069.0 avail Men |
总量内存大小 | 空闲内存大小 | 占用内存大小 | 缓存内存大小: 要保存/要加载的硬盘数据 可用内存大小 |
⑤ 参数分析:
PID 进程 idUSER 进程所有者的用户名PR 优先级NI nice值。负值表示高优先级,正值表示低优先级VIRT 虚拟内存总量,单位kb 。 VIRT=SWAP+RESRES 长住内存,进程使用的、未被换出的物理内存大小,单位kb。 RES=CODE+DATASHR 共享内存大小,单位kbS 进程状态(D= 不可中断的睡眠状态 、R= 运行、 S= 睡眠 、T= 跟踪 / 停止 、Z= 僵尸进程)%CPU 上次更新到现在的 CPU 时间占用百分比%MEM 进程使用的物理内存百分比TIME+ 运行时长,使用CPU的 时间总计,单位 1/100 秒COMMAND 进程名称
四、进程的前后台调用
前后台调用的命令:
命令 | 功能 |
Ctrl+Z | 把占用shell的进程打入后台挂起 |
jobs | 查看当前shell中在后台的所有工作 |
bg job号 | 把后台挂起的进程运行起来 |
fg job号 | 把后台进程调回前台 |
gedit & | 使一开始打开进程时,运行进程在后台 |
首先打开进程,这个进程占用了当前的终端,并在里面输入内容。
当命令占用命令行时,可以用 Ctrl+Z 把占用命令行的进程打入后台并挂起,此时可以在终端执行命令,但不可使用命令行。
用 jobs 命令查看后台的所有进程,包括已经挂起和运行的,然后用 bg + job号 让后台挂起的进程运行起来。
用 fg + job号 将后台进程调回前台
gedit & 运行进程并在后台运行
五、进程的优先级
在 Linux 中,每个进程都有一个优先级。优先级决定了进程在系统资源分配中的先后顺序。Linux 中的进程优先级范围从 -20 到 +19,其中 -20 为最高优先级,+19 为最低优先级,优先级越高的进程越有可能被 CPU 优先调度执行。
1.优先级的种类
静态优先级:静态优先级是在创建进程时分配的,通常由管理员或程序员指定。静态优先级决定了进程的基本优先级,可以通过 nice 命令来设置,范围为 -20(最高优先级) 到 +19(最低优先级),数值越小优先级越高。
动态优先级:动态优先级是根据进程的行为和运行情况自动调整的(如 CPU 使用时间、睡眠时长等),以平衡系统资源分配。在 Linux 中,使用调度算法来动态调整进程的优先级。当一个进程使用 CPU 时间较长时,系统会降低它的优先级,让其他进程有更多的执行时间。而当一个进程处于等待 IO 等待状态时,系统会提高它的优先级,以便快速完成 IO 操作。
2.静态优先级的调整方法
打开查看优先级的监控,实时观察。
renice -5 进程id:更改指定进程的优先级
renice -5 51291 命令将该进程优先级从 0 升高到 -5。
renice 5 51291 命令将该进程优先级从 -5 降低到 5。
nice -n 10 gedit :在打开命令行之前更改优先级为 10 ,优先级相对较低。
六、进程信号
1.进程信号的概念
在 Linux 中,进程信号(Process Signal)是一种软件中断机制,它可以由系统、其他进程或进程自身产生,用于通知进程发生了某个特定的事件。进程接收到信号后,会根据信号的类型和进程的当前状态来决定如何响应。
2.常见的信号类型
信号名称 | 信号编号 | 功能 | 说明 |
SIGHUP | 1 | 在不结束进程的情况下更改配置 | 终端断开连接时发送给与该终端关联的进程,常 用于重新加载配置文件 |
SIGINT | 2 | 清除进程在内存中的数据 | 用户在终端按下 Ctrl+C 时发送给当前前台进程 |
SIGQUIT | 3 | 终止进程并生成核心转储文件 | 用户在终端按下 Ctrl+C 时发送给当前前台进程 |
SIGTERM | 15 | 终止进程 | 通常用于请求进程正常终止,是系统默认的终止 信号 |
SIGKILL | 9 | 强制终止进程 | 不能被捕获、阻塞或忽略,用于强制终止无法正 常响应的进程 |
SIGCONT | 18 | 继续执行暂停的进程 | 用于恢复被暂停的进程 |
SIGSTOP | 19 | 暂停进程 | 不能被捕获、阻塞或忽略,用于暂停进程的执行 |
SIGSTOP | 20 | 暂停进程 | 可以被捕获、阻塞或忽略,用于暂停进程的执行 |
3.进程信号处理命令的使用
kill 进程信号 pid (处理精确指定的进程)killall 进程信号 进程名字 (按照进程名称批量处理进程)pkill 进程信号 进程条件 (按照条件处理进程)
① kill 进程信号 pid
先打开一个进程,并在后台运行,也得知该进程的 pid ,用 kill -9 55388 命令强制退出该进程。
② killall 进程信号 进程名字
先打开四个名为 vim 的进程,然后在另一个终端输入 killall -9 vim 的命令,便可直接结束名为 vim 的所有进程。
执行命令前:
执行命令后:
③ pkill 进程信号 进程条件
分别在两个终端打开名为 lxt 的进程
然后在另外一个终端执行 pkill -9 -u lxt 的命令后,条件名为 lxt 的进程便被强制终止。
七、守护进程
1.守护进程的定义
守护进程也称为精灵进程(Daemon),是运行在后台的一种特殊进程。它不与终端直接交互,通常在系统启动 时自动启动,并在系统关闭时才停止。它独立于控制中断并且周期性的执行某种任务或者等待处理某些发生的事件。
Linux系统启动是会启动很多服务进程,这些系统服务进程没有控制终端,不能直接和用户交互。其他进程都是在用户登录或运行程序时创建。在运行结束或者用户注销时终止,但系统服务进程不受用户登录注销的影响,它们一直运行在后台,确保系统的正常运行。
2.守护进程的特点
- 后台运行:守护进程在后台持续运行,不与任何终端关联,不会因终端关闭而停止。
- 独立于用户登录:它不受特定用户登录或注销的影响,始终在系统中运行,为系统提供各种服务。
- 自动启动:一般在系统启动过程中,会根据配置自动启动相应的守护进程,确保系统服务的正常运行。
3.systemctl守护进程管理命令
命令 | 功能 |
systemctl status firewalld | 查看防火墙状态 |
systemctl stop firewalld | 关闭防火墙 |
systemctl start firewalld | 打开防火墙 |
systemctl disable firewalld | 设定服务开机不启动 |
systemctl enable firewalld | 设定服务开机启动 |
systemctl disable --now firewalld | 设定服务开机不启动,并当前关闭服务 |
systemctl enable --now firewalld | 设定服务开机启动,并当前开启服务 |
systemctl list-units | 查看系统所有服务的当前状态 |
systemctl list-units-files | 查看所有服务的开机状态 |
systemctl list-dependencies | 列出守护进程的依赖性 |
systemctl mask firewalld | 冻结服务(无法关闭和开启当前服务) |
systemctl unmask firewalld | 解锁(可关闭和开启当前服务) |
systemctl get-default | 设定系统运行模式 |
运行结果为: multi-user.target 无图形网络模式 graphical.target 有图形的网络模式 | |
systemctl set-default | 查看系统运行模式 |
系统运行模式(0-6): 0 关机 1 单用户模式 2、3、4 无图形网络模式 5 图形网络模式 6 重启 |