一、进程和线程的概念
1.进程
(1)概念
进程是程序在操作系统中的一次执行过程,是系统进行资源分配和调度的基本单位。进程是程序的执行实例,拥有独立的资源(如内存、文件描述符等)。每个进程在创建时会被分配唯一的进程ID,即为PID,也叫进程编号。
(2)特点
资源隔离:进程拥有独立的虚拟地址空间。
独立性:进程崩溃通常不会直接影响其他进程,代表了其高隔离性的特点。
通信成本高:进程间通信(IPC)需通过管道、共享内存、信号、消息队列等机制。
创建开销大:fork()系统调用会复制父进程的上下文。
2.线程
(1)概念
线程是进程中的一个执行单元,是 CPU 调度和分派的基本单位,是进程内的执行单元,共享进程的资源(如内存、文件句柄),但拥有独立的栈和寄存器上下文。
(2)特点
资源共享:线程直接共享进程的内存、全局变量等,通信更高效。
轻量级:线程创建和切换的开销远小于进程。
同步需求:共享资源需通过互斥锁(mutex)、信号量(semaphore) 等机制避免竞态条件。
高风险:一个线程崩溃可能导致整个进程终止(共享地址空间)。
3.进程的状态
运行态(Running) | 进程正在 CPU 上执行,系统中处于运行态的进程在某一时刻只有一个(单核 CPU),多核 CPU 环境下可以有多个。 |
就绪态(Ready) | 进程已经准备好运行,只等待 CPU 资源分配。 |
阻塞态(Blocked) | 进程因等待某一事件(如 I/O 操作完成、信号量获取等)而暂时无法继续执行。 |
停止态(Stopped) | 进程被暂停执行,通常是收到了特定信号(如 SIGSTOP)。 |
僵死态(Zombie) | 进程已经终止,但父进程尚未回收其资源(如进程描述符等)。 |
4.进程和线程之间的联系与对比
(1)联系:
线程隶属于进程,且同一进程内的线程共享同一个进程ID(PID),但每个线程有唯一的线程ID(TID)。
(2)对比:
进程 | 线程 | |
资源分配 | 拥有独立内存空间与系统资源,如文件描述符、打开文件等,进程间资源隔离,一个进程崩溃不影响其他进程,像办公软件进程崩溃不影响浏览器进程。 | 共享所属进程资源,无独立系统资源,但有独立执行栈与程序计数器记录执行状态。 |
调度 | 是系统资源分配和调度基本单位,调度时需保存和恢复内存映射、寄存器状态等大量上下文信息,开销大。 | 是 CPU 调度和分派基本单位,因共享进程资源,调度时仅保存和恢复执行栈、程序计数器等少量信息,开销小。 |
创建、销毁和切换开销 | 创建要分配独立内存与系统资源,销毁需释放,创建、销毁及切换时保存和恢复大量上下文信息,开销均大。 | 创建和销毁仅分配、释放少量资源,切换时保存和恢复少量上下文信息,开销小且速度快。 |
通信机制 | 进程间通信(IPC)依靠管道、消息队列等专门机制,较复杂,要额外同步、互斥操作保证数据安全一致。 | 可直接访问共享内存变量来通信,方式简单高效,但多线程同时访问共享资源易出现数据竞争,需锁等同步机制保障线程安全。 |
健壮性 | 进程间资源隔离,健壮性较高,一个进程崩溃通常不影响其他进程。 | 同一进程内线程共享资源,一个线程崩溃可能致使整个进程崩溃,健壮性较低。 |
二、查看进程状态的相关命令
查看进程状态的命令有(常用):ps、ps ax、ps aux、pgrep、pidof、top
1、ps相关命令(ps、ps ax、ps aux)
ps命令的常用参数表
参数 | 说明 | 示例 |
基础选项 | ||
a | 显示所有用户的进程(包括其他用户)。 | ps a |
x | 显示无控制终端的进程(如守护进程)。 | ps x |
ax | 组合使用:显示所有进程(包括无终端的进程)。 | ps ax |
信息控制 | ||
-o <字段> | 自定义输出字段(支持 pid , user , %cpu , comm , tty , stat 等)。 | ps axo pid,user,comm,%cpu |
u | 显示详细资源占用(用户、CPU、内存等,类似 ps aux )。 | ps aux |
-e | 显示所有进程(等效于 ax ,但属于Unix风格参数)。 | ps -e |
筛选过滤 | ||
-p <PID> | 显示指定PID的进程。 | ps ax -p 1234 |
-U <用户> | 显示指定用户的进程。 | ps ax -U root |
-C <命令> | 按进程名过滤(支持部分匹配)。 | ps ax -C nginx |
--ppid <PID> | 显示父进程为指定PID的子进程。 | ps ax --ppid 1 |
格式化输出 | ||
--sort | 按字段排序(+%cpu 升序,-%mem 降序)。 | ps ax --sort=-%cpu |
-H | 显示进程层级关系(树形结构)。 | ps axH |
-f | 显示完整格式(包括命令行参数)。 | ps axf |
线程查看 | ||
-L | 显示线程(LWP列)。 | ps axL |
-T | 显示线程(SPID列)。 | ps axT |
ps ax的默认输出列
列名 | 说明 | 示例 |
PID | 进程的唯一标识符(Process ID)。 | 1234 |
TTY | 进程关联的终端设备: - ? :无控制终端(如守护进程)。- pts/0 :虚拟终端或SSH会话。 | ? 或 pts/0 |
STAT | 进程状态(由多个字符组成,见下方详细说明)。 | Ss , R+ , D |
TIME | 进程累计占用CPU的时间(格式为分钟:秒 )。 | 00:01 , 10:23 |
COMMAND | 启动进程的命令名称或命令行参数: - [] 表示内核线程。 | /usr/bin/nginx , [kworker] |
ps aux的默认输出列
列名 | 说明 | 示例 |
USER | 进程的所有者(用户账号)。 | root , nginx |
PID | 进程的唯一标识符(Process ID)。 | 1234 |
%CPU | 进程占用CPU的百分比(单位:%),基于最近一次刷新周期内的使用情况。 | 0.5 , 99.0 |
%MEM | 进程占用物理内存的百分比(单位:%)。 | 2.3 , 15.8 |
VSZ | 虚拟内存大小(Virtual Memory Size,单位:KB),即进程申请的虚拟内存总量。 | 123456 (约123MB) |
RSS | 实际使用的物理内存(Resident Set Size,单位:KB),即进程当前占用的非交换内存。 | 65432 (约65MB) |
TTY | 进程关联的终端设备: - ? :无控制终端(如守护进程)。- pts/0 :虚拟终端或SSH会话。 | ? 或 pts/0 |
STAT | 进程状态(由多个字符组成,见下方详细说明)。 | Ss , R+ , Dl |
START | 进程启动时间(格式为小时:分钟或日期,取决于运行时长)。 | 10:00 , Jan01 |
TIME | 进程累计占用CPU的时间(格式为分钟:秒 )。 | 00:01 , 120:45 |
COMMAND | 启动进程的命令名称或命令行参数: - [] 表示内核线程。 | /usr/bin/nginx , [kworker] |
2、pgrep
作用:
pgrep
用于根据 进程名、用户、组等条件快速查找进程PID,默认仅输出匹配的进程ID(PID)。
与ps
/grep
组合相比,pgrep
更高效且语法简洁。
pgrep常用参数表
参数 | 说明 | 输出新增内容 | 示例 |
基础过滤 | |||
-u <用户> | 按用户过滤进程(用户名或UID)。 | 仅PID | pgrep -u root |
-G <组> | 按组过滤进程(组名或GID)。 | 仅PID | pgrep -G www-data |
-x | 精确匹配进程名(需全名匹配)。 | 仅PID | pgrep -x sshd |
输出控制 | |||
-l | 显示进程名(与PID一同输出)。 | 进程名 | 1234: nginx |
-a | 显示完整命令行(需结合-l )。 | 完整命令 | 1234: nginx: worker process |
-c | 输出匹配进程的数量(计数)。 | 数字 | 3 |
-d <分隔符> | 自定义PID分隔符(默认为换行)。 | 无,格式变化 | pgrep -d ',' nginx → 1234,5678 |
信号与状态 | |||
-f | 匹配完整命令行(而非仅进程名)。 | 无,过滤条件变化 | pgrep -f "nginx -g" |
-n | 仅显示最新(最近启动)的进程PID。 | 仅PID | pgrep -n nginx |
-o | 仅显示最旧(最早启动)的进程PID。 | 仅PID | pgrep -o nginx |
3、pidof
命令:
pidof 进程名称示例
pidof nginx # 输出:1234 5678 (多个nginx进程的PID)
pidof sshd # 输出:8910 (sshd守护进程的PID)
显示单个PID(-s):
pidof -s <进程名> # 仅返回一个PID(通常是最新的进程)示例
pidof -s python3 # 输出:9999 (最近启动的Python3进程PID)
pidof常用参数表
参数 | 说明 |
-s | 仅返回一个PID(单实例进程适用)。 |
-c | 仅返回与当前运行环境相同根目录(chroot)下的进程PID。 |
-x | 同时匹配执行该脚本的Shell进程PID(用于脚本文件)。 |
-o <PID> | 排除指定PID的进程(可多次使用,如 -o 1234 -o 5678 )。 |
-d <分隔符> | 自定义PID分隔符(默认是空格)。 |
4、top
概念:
top
是 Linux 系统中用于 实时监控系统资源使用情况和进程状态 的核心命令行工具。它能动态显示 CPU、内存、交换分区、进程负载等关键指标,帮助用户快速定位性能瓶颈。
(1)top 的核心功能
① 实时刷新:
默认每 3 秒更新一次数据(可配置)。
② 多维度展示:
系统资源概览:
CPU、内存、负载、运行时间等。
进程列表:
按资源占用排序的进程详情(PID、用户、CPU、内存等)。
③ 交互式操作:
支持动态排序、筛选、终止进程等操作。
(2)top内容详解(实例演示)
第一行:系统时间、运行时长、登录用户数、平均负载。
第二行:进程总数及状态统计(运行、睡眠、停止、僵尸)。
第三行:CPU 使用率(用户态 us、内核态 sy、空闲 id、等待I/O wa 等)。
第四行:物理内存使用情况(总量、空闲、已用、缓存)。
第五行:交换分区使用情况。
关键字眼:
PID:进程ID。
USER:进程所有者。
%CPU:CPU 占用百分比。
%MEM:物理内存占用百分比。
VIRT:虚拟内存总量(KB)。
RES:实际物理内存占用(KB)。
SHR:共享内存大小(KB)。
S:进程状态(R=运行, S=睡眠, Z=僵尸等)。
TIME+:累计 CPU 占用时间。
三、进程的前/后台调用
<ctrl>+<z>:
在终端中,当一个进程正在前台运行并占用着 shell 时,按下 Ctrl + Z
组合键可以将该进程暂停并打入后台挂起。此时,进程处于停止状态,但并未终止,它会释放对终端的控制权,让用户可以在 shell 中继续输入其他命令。
bg:
用于将后台挂起的进程在后台运行起来。
fg:
用于把后台进程调回前台。
命令 &:
在命令后面加上 &
,可以让该命令对应的进程在后台运行。
jobs:
命令用于查看当前 shell 中在后台的所有工作,即显示所有后台进程的信息,包括进程的编号、状态以及对应的命令等。
四、进程的优先级
1、概念
在 Linux 系统中,进程优先级决定了进程获取 CPU 时间的顺序。优先级高的进程会更频繁地被调度执行,这对系统性能调优和资源管理至关重要。
2、优先级种类
(1)概念
进程也分为“可控的”和“不可控的”,“可控”,说明进程可以被用户或管理员进行修改或手动设置,这种即为静态优先级,而“不可控”,即不能被用户或管理员进行修改等操作,由系统内核根据进程的运行状态来调整(如等待时间、CPU 使用率),优化调度公平性,避免低优先级进程长期饥饿,这种即为动态优先级。
(2)静态优先级的调节
用户通过 nice 或 renice 设置,范围 -20(最高)到 19(最低),能直接影响普通进程的初始调度权重。
nice值
nice值用来调整控制进程优先级的,nice值越低(越负),优先级就越高;Nice 值范围:-20(最高优先级)到 19(最低优先级),默认值为 0
命令格式:
nice -n <调整值> <命令> # 调整值为目标 Nice 值与默认值(0)的差值
示例 :
解释:用指定权限-5来打开cat命令
renice值
renice命令可以修改进程的nice值,如renice -5 3595,其中 -5 为你想要修改的nice值为多少,后面的编号3595即为进程编号
Tips:查看进程编号可以用监视(watch)来监控进程的pid,即可看到进程编号,也可以用vim &来查看
命令格式:
renice -5(想要修改的nice值) 16410(进程编号)
(3)进程状态字符解释
字符 | 说明 |
R | 进程正在运行或在就绪队列中等待 CPU 分配。 |
S | 可中断睡眠:等待事件完成(如 I/O 操作、信号)。 |
D | 不可中断睡眠:通常等待硬件操作(如磁盘 I/O),不能被信号中断。 |
Z | 僵尸进程:进程已终止,但其退出状态未被父进程回收。 |
T | 进程被作业控制信号(如 SIGSTOP 、SIGTSTP )暂停。 |
t | 进程被调试器暂停(如通过 ptrace 跟踪)。 |
X | 进程完全终止(极少见,通常瞬间消失)。 |
< | 高优先级:进程的 Nice 值为负(优先级高于默认)。 |
N | 低优先级:进程的 Nice 值为正(优先级低于默认)。 |
s | 会话领导者:进程是会话(Session)的首进程(如 Shell 进程)。 |
l | 多线程:进程是多线程的(有多个轻量级进程 LWP)。 |
+ | 前台进程组:进程属于终端的前台进程组(可接收输入)。 |
L | 锁定内存:进程将部分内存锁定(如通过 mlock 避免换出)。 |
I | 空闲进程:内核线程处于空闲状态(某些系统显示为 I )。 |
五、进程信号
1.概念:
进程信号是操作系统用于在进程之间传递事件通知的一种机制,它可以让操作系统、其他进程或进程自身向某个进程发送信号,以通知该进程发生了特定的事件,进程接收到信号后会根据信号的类型和自身的状态做出相应的反应。
2.用户可控制的进程信号(表格)
信号名称 | 信号值 | 默认行为 | 典型用途 | 可否捕获/忽略 |
SIGHUP | 1 | 终止进程 | 通知进程重新加载配置(如 nginx -s reload )。 | 可 |
SIGINT | 2 | 终止进程 | 用户按下 Ctrl+C 中断前台进程。 | 可 |
SIGQUIT | 3 | 终止进程并生成核心转储 | 用户按下 Ctrl+\ 强制终止并调试(生成 core dump)。 | 可 |
SIGKILL | 9 | 强制终止进程 | 无条件终止进程(无法被捕获或忽略)。 | 否 |
SIGTERM | 15 | 终止进程 | 请求进程正常退出(允许清理资源),默认的 kill 信号。 | 可 |
SIGSTOP | 17,19,23 | 暂停进程 | 暂停进程(不可被捕获或忽略),用户按下 Ctrl+Z (实际发送 SIGTSTP )。 | 否 |
SIGCONT | 18,25,26 | 继续运行 | 恢复被暂停的进程(如 bg /fg 命令)。 | 可 |
SIGTSTP | 20 | 暂停进程 | 用户按下 Ctrl+Z 暂停前台进程(可捕获处理)。 | 可 |
SIGUSR1 | 10 | 终止进程 | 用户自定义用途(如通知进程切换日志文件)。 | 可 |
SIGUSR2 | 12 | 终止进程 | 用户自定义用途(如通知进程更新配置)。 | 可 |
3、控制进程信号的命令
(1)killall命令
该命令可以向内核询问一个进程存不存在,如:
killall -<信号名或值> <进程名> # 向所有同名进程发送信号如
killall -0(信号编号) gedit(进程的名字或编号)
其中的 -0 位为信号编号,且有许多其他数字代表,但用户可以控制的常用信号只有代码这些(上面的表有详细的介绍):-1 -2 -3 -15 -9 -18 -19 -20
(2)kill命令
kill可以精准的将一个进程杀死(结束)如:
kill -<信号名或值> <PID> # 向指定 PID 发送信号如
kill -9(信号编号) 16410(进程的名字或编号)
(3)pkill命令
pkill -<信号名或值> <模式> # 按模式匹配进程并发送信号
pkill可以终止一个用户
我们先创建一个用户test来测试pkill命令,并登录上此test用户
另起一个终端命令行,输入pkill命令
六、systemd守护进程
1.概念
守护进程(Daemon)是一种在后台持续运行的特殊进程,它不与终端直接交互,通常在系统启动 时自动启动,并在系统关闭时才停止。
2.作用
守护进程的设计目的是为系统提供各种服务,例如网络服务(如 HTTP 服务器、FTP 服务器)、日 志服务、定时任务服务等。它们默默地在后台运行,为其他进程和用户提供支持,确保系统的正常 运行。
3.特性(核心)
特性 | 说明 |
无控制终端 | 脱离终端运行(TTY 显示为 ? ),不接收用户直接输入。 |
后台运行 | 默默执行任务,不占用用户交互界面。 |
独立会话 | 创建新会话(Session)并成为会话领导者(Session Leader)。 |
脱离父进程 | 通过两次 fork() 脱离原进程,由 init (PID=1)接管。 |
固定工作目录 | 通常将工作目录设置为根目录(/ )或特定目录(如 /var/run )。 |
日志输出 | 将标准输入/输出重定向到文件(如 /var/log )或 syslog 。 |
4.常用命令表
命令 | 作用 | 示例 |
systemctl start <服务名> | 启动服务 | sudo systemctl start nginx |
systemctl stop <服务名> | 停止服务 | sudo systemctl stop sshd |
systemctl restart <服务名> | 重启服务 | sudo systemctl restart mysql |
systemctl reload <服务名> | 重新加载配置(不重启服务) | sudo systemctl reload nginx |
systemctl status <服务名> | 查看服务状态 | systemctl status docker |
systemctl enable <服务名> | 启用开机自启 | sudo systemctl enable httpd |
systemctl disable <服务名> | 禁用开机自启 | sudo systemctl disable postfix |
systemctl is-enabled <服务名> | 检查服务是否开机自启 | systemctl is-enabled cron |
systemctl mask <服务名> | 禁用服务(阻止手动或自动启动) | sudo systemctl mask apache2 |
systemctl unmask <服务名> | 解除禁用 | sudo systemctl unmask apache2 |