Linux系统编程Day11 -- 进程状态的优先级和特性
往期内容回顾
进程属性和常见进程
进程管理
理解计算机的软硬件管理
前言
进程是操作系统资源管理和任务调度的基本单位。进程管理的核心目标是协调多个进程的运行,确保系统高效、稳定地工作。了解进程的状态变化和优先级机制,有助于理解操作系统如何调度任务,实现多任务并发。
本文将深入介绍进程的常见状态及其含义,阐述进程优先级的分类与调度作用,帮助读者全面掌握进程管理的基础知识。
主要内容介绍
-
回顾进程的常见状态
-
进程状态的生命周期及状态转换
-
进程优先级的分类
-
优先级调度的基本策略
一、回顾进程常见状态
进程在其生命周期中会经历多个状态,每个状态反映进程当前的执行情况或等待条件。操作系统根据这些状态来管理进程调度。参考:进程属性和常见进程
1. 新建(New)
进程刚被创建,系统正在为其分配资源,尚未进入就绪队列。
2. 就绪(Ready)
进程已具备运行条件,等待CPU分配。进程虽然不能立即运行,但已准备好执行。
3. 运行(Running)
进程获得CPU,正在执行指令。
4. 阻塞(Blocked / Waiting)
进程因等待某些事件(如I/O操作、信号等)而暂停执行,无法继续运行,直到等待条件满足。
5. 挂起(Suspended)
进程被操作系统临时暂停,可能因资源紧张被换出内存,等待重新调入。
6. 停止(Stopped)
进程被用户或系统信号暂停,不再接受CPU调度,等待恢复。
7. 僵尸(Zombie)
进程执行结束,但其父进程尚未回收退出状态,系统保留部分进程信息。
测试僵尸进程
#include <stdio.h> #include <unistd.h> #include <stdlib.h>int main(){pid_t id = fork();if(id == 0){ while(1){printf("Child Process and PID = %d, PPID = %d, id = %d\n",getpid(),getppid(),id);sleep(5);exit(-1);} } else if (id > 0) {while(1){printf("Father Process and PID = %d, PPID = %d, id = %d\n",getpid(),getppid(),id);sleep(1);} } }
这里我们建立一个子进程和一个父进程,其中我们终止子进程,让父进程继续运行。
同时我们写了一段脚本来监视该程序运行时的进程
while :; do ps ajx | head -1 | ps ajx | grep 你的程序名 | grep -v grep | sleep 1; done
运算程序,然后运行监视脚本。
输出结果:
Father Process and PID = 160081, PPID = 159876, id = 160082
Child Process and PID = 160082, PPID = 160081, id = 0
Father Process and PID = 160081, PPID = 159876, id = 160082
Father Process and PID = 160081, PPID = 159876, id = 160082
你会发现,很快子进程退出了,只显示父进程在执行,并且子进程显示为僵尸进程z+ <defunct>。
8、孤儿进程(Orphan)
父进程终止后,子进程依然运行,由操作系统将其“收养”并挂载到init进程下
测试孤儿进程
#include <stdio.h> #include <unistd.h> #include <stdlib.h>int main(){pid_t id = fork();if(id == 0){ while(1){printf("Child Process and PID = %d, PPID = %d, id = %d\n",getpid(),getppid(),id);sleep(1);} } else if (id > 0) {while(1){printf("Father Process and PID = %d, PPID = %d, id = %d\n",getpid(),getppid(),id);sleep(1);} } }
这里我运行这段代码并且监视它们的进程
这是运行中的两个进程:其中 PID 161470 是父进程, 161471是子进程,此时如果我们kill掉父进程会如何呢?
kill -9 161470
此时它的父进程被回收了,而子进程仍然在运行,且它的父进程变为pid 1
那么谁是pid = 1的进程呢?
pid = 1 其实对应的是我们的操作系统。则孤儿进程被操作系统领养了。且前台创建的子进程如果变成了孤儿进程,则进程将会变成后台进程,且无法被 ctrl+c停止掉。
二、进程状态生命周期及转换
进程状态之间可以互相转换,典型的状态流转为:
新建 → 就绪 → 运行 → 阻塞 → 就绪 → 运行 → 终止(包括僵尸)
-
调度程序根据调度算法在就绪和运行状态间切换进程。
-
进程等待I/O等事件时进入阻塞状态。
-
进程结束后进入终止状态,若父进程未回收则成为僵尸。
三、进程优先级
优先级是操作系统用来决定进程调度先后顺序的重要依据。优先级高的进程通常优先获得CPU资源(权限是决定你能不能做,优先级决定你的顺序,前提你有权限)。
1. 为什么需要优先级
-
资源有限:CPU 同时只能执行一个进程(单核情况下),需要排队。
-
任务紧急程度不同:
-
比如视频播放需要实时处理(高优先级)
-
后台下载文件可以等一等(低优先级)
-
-
提升系统响应:让重要或紧急任务更快运行。
2. Linux 中的优先级
在 Linux 中,优先级有两种相关概念:
-
静态优先级(Static Priority)
-
范围一般是 0139(099 为实时进程,100~139 为普通进程)
-
实时进程优先级固定,不会随运行调整。
-
-
Nice 值(用户可调)
-
范围:-20(最高优先级) ~ 19(最低优先级)
-
普通用户可以调高自己的 Nice 值(降低优先级),但不能降低 Nice 值(提高优先级),除非是 root。
-
3、查看进程的优先级
利用 ps -la 查看当前用户运行的进程,然后可以看到PRI这个字符代表的是priority《优先级》,NI 则代表的是nice值, 最终优先级 = 老的优先级 + nice值。
# 查看所有进程的优先级和 nice 值 ps -eo pid,comm,pri,ni # 启动进程时设定 nice 值(降低优先级) nice -n 10 my_program # 修改已有进程的 nice 值 renice -n -5 -p 1234 # 需要 root 权限
四、进程的几个重要特性
1. 竞争性(Competition)
定义:多个进程争夺有限的系统资源(CPU、内存、I/O、网络带宽等)的现象。
-
系统资源有限,所以不能让所有进程同时无限制运行。
-
竞争会引发调度、优先级、锁机制等问题。
-
例子:
-
两个程序都想写同一个文件(可能需要加文件锁)
-
多个任务都需要 CPU 时间
-
与调度的关系:调度器要解决这种竞争,让系统既高效又公平
2. 独立性(Independence)
定义:进程拥有自己独立的资源(内存空间、寄存器状态、文件描述符等),即便在同一系统运行,也互不干扰。
-
一个进程崩溃不会直接破坏另一个进程(除非它们通过共享资源或 IPC 交互)。
-
独立性保证了多任务系统的稳定性和安全性。
例子:
-
你在终端编译代码(gcc 进程)时,播放器(vlc 进程)也在放音乐,它们的内存和状态互不干涉。
3. 并行(Parallelism)
定义:物理上的同时执行。
-
需要多核 CPU 或多台计算机(分布式计算)。
-
不同的进程(或线程)真的在同一时间运行在不同的处理单元上。
例子:
-
4 核 CPU 同时运行 4 个计算任务,各用一个核心。
-
超算集群同时处理成千上万的任务。
4. 并发(Concurrency)
定义:逻辑上的同时执行(实际上是交替执行,但速度足够快,看起来像是同时执行)。
-
常见于单核 CPU 通过时间片轮转来切换任务。
-
每个进程只运行一小段时间,然后操作系统切换到另一个进程。
例子:
-
单核电脑同时下载文件、听音乐、打字——其实是 CPU 快速切换在不同进程间执行。
5. 对比与联系
概念 | 核心含义 | 需要多核? | 例子 |
---|---|---|---|
竞争性 | 抢资源 | 否 | 多个进程抢 CPU |
独立性 | 互不干扰 | 否 | 终端编译与播放器 |
并行 | 物理同时 | 是 | 4 核同时跑 4 任务 |
并发 | 逻辑同时 | 否 | 单核快速切换 |
┌─────────────────────────────────────┐
│ 进程特性 │
│ │
│ 竞争性 → 抢资源 │
│ 独立性 → 各自运行,不互干扰 │
│ 并行 → 多核同时执行 │
│ 并发 → 单核快速切换,假装同时执行 │
└─────────────────────────────────────┘
简单总结:
进程管理是操作系统协调和分配 CPU、内存等资源的核心机制,它通过进程状态(如运行、就绪、阻塞、停止、僵尸)来跟踪进程的生命周期,并通过调度算法决定哪个进程获得 CPU 时间。
-
运行(R):进程正在占用 CPU 执行。
-
就绪(S):具备运行条件,等待 CPU 调度。
-
阻塞(D/S):等待 I/O 或事件完成。
-
停止(T):暂停执行,可通过信号恢复。
-
僵尸(Z):进程已结束但父进程尚未回收资源。
进程优先级决定调度顺序,高优先级进程会更快获得 CPU;Linux 中优先级分为静态优先级(nice 值,-20 到 19)和动态优先级(调度器根据运行情况调整),以在响应速度与公平性之间平衡。