mobile wallpaper 1mobile wallpaper 2mobile wallpaper 3mobile wallpaper 4mobile wallpaper 5
1299 字
3 分钟
OS笔记(三):进程控制
2026-06-05

OS笔记(三):进程控制#

本文是操作系统笔记系列的第三篇,详细讲解操作系统如何通过原语来控制进程的创建、终止、阻塞、唤醒和切换。


📚 目录#


一、什么是原语?#

1.1 原语的定义#

原语(Primitive)是操作系统内核中由若干指令组成的原子操作,执行过程一气呵成,不可中断

1.2 如何保证原子性?#

使用 关中断指令开中断指令 这两个特权指令:

关中断指令 ← 关闭中断响应
操作1
操作2
...
开中断指令 ← 恢复中断响应

原理:CPU执行关中断指令后,不再检查中断信号,直到执行开中断指令后才恢复。这样中间的指令序列就不可被中断了。

1.3 为什么需要原语?#

进程控制涉及修改PCB、队列等关键数据结构,如果不原子执行,可能出现数据不一致的错误。


二、进程创建#

2.1 创建原语的执行步骤#

步骤操作
1申请空白PCB
2为新进程分配所需资源(内存、文件等)
3初始化PCB(PID、程序计数器、寄存器等)
4将PCB插入就绪队列

2.2 引起进程创建的事件#

事件说明示例
用户登录用户登录系统时创建Shell进程SSH登录
作业调度从外存调入作业执行批处理系统
提供服务OS为用户请求创建服务进程打印请求
应用请求进程主动创建子进程fork()系统调用

三、进程终止#

3.1 撤销原语的执行步骤#

步骤操作
1从PCB集合中找到终止进程的PCB
2若进程正在运行,立即剥夺CPU
3终止其所有子进程(级联终止)
4将该进程拥有的所有资源归还给父进程或OS
5删除PCB

3.2 引起进程终止的事件#

事件说明示例
正常结束进程执行完毕程序运行结束
异常结束遇到致命错误段错误、除零错误
外界干预被其他进程或管理员终止kill命令

四、进程阻塞与唤醒#

4.1 阻塞原语#

步骤操作
1找到要阻塞的进程对应的PCB
2保护进程运行现场,将PCB状态设为阻塞态
3将PCB插入相应事件的等待队列

4.2 唤醒原语#

步骤操作
1在事件等待队列中找到PCB
2将PCB从等待队列中移除,设为就绪态
3将PCB插入就绪队列

注意:阻塞是进程主动调用的(如等待I/O),唤醒是由其他进程或OS在事件完成时调用的。


五、进程切换#

5.1 切换原语的执行步骤#

步骤操作
1将运行环境信息(寄存器值等)存入当前进程的PCB
2将当前PCB移入相应队列(就绪/阻塞)
3选择另一个进程执行,更新其PCB
4根据新进程的PCB恢复运行环境

5.2 引起进程切换的事件#

事件说明
时间片用完当前进程时间片到,切换到下一个就绪进程
进程阻塞当前进程主动阻塞,切换到其他就绪进程
更高优先级进程就绪抢占式调度下,高优先级进程抢占CPU

原语总结


六、Linux实战:进程控制#

6.1 创建进程:fork()#

# 在C语言中使用fork()创建子进程
cat > fork_demo.c << 'EOF'
#include <stdio.h>
#include <unistd.h>
int main() {
pid_t pid = fork();
if (pid > 0) {
// 父进程
printf("父进程 PID=%d, 子进程 PID=%d\n", getpid(), pid);
} else if (pid == 0) {
// 子进程
printf("子进程 PID=%d, 父进程 PID=%d\n", getpid(), getppid());
}
return 0;
}
EOF
gcc fork_demo.c -o fork_demo
./fork_demo

6.2 终止进程#

# 正常终止
kill <PID>
# 发送SIGTERM信号(可被捕获)
kill -15 <PID>
# 强制终止(不可捕获)
kill -9 <PID>
# 按名称终止
pkill -f "python3 my_script.py"
# 终止所有同名进程
killall python3

6.3 进程状态管理#

# 暂停进程(发送SIGSTOP)
kill -STOP <PID>
# 恢复进程(发送SIGCONT)
kill -CONT <PID>
# 实际操作
sleep 100 &
PID=$!
echo "进程 PID=$PID 已启动"
sleep 2
kill -STOP $PID
echo "进程已暂停"
sleep 2
kill -CONT $PID
echo "进程已恢复"

6.4 查看进程关系#

# 查看进程树
pstree -p
# 查看特定进程的父进程
ps -p <PID> -o pid,ppid,cmd
# 查看子进程
ps --ppid <PID>

6.5 Shell中的进程控制#

# 前台运行
./my_program
# 后台运行
./my_program &
# 查看后台任务
jobs
# 切换到前台
fg %1
# 继续后台运行
bg %1
# nohup保持运行(退出终端后继续)
nohup ./my_program &

七、本章小结#

核心概念#

概念要点
原语原子操作,用关中断/开中断保证
创建原语申请PCB→分配资源→初始化→插入就绪队列
终止原语找PCB→剥夺CPU→终止子进程→回收资源→删除PCB
阻塞原语保护现场→设阻塞态→插入等待队列
唤醒原语从等待队列移除→设就绪态→插入就绪队列
切换原语保存环境→移队列→选新进程→恢复环境

考研/期末常见考点#

  1. 原语的原子性如何保证(关中断/开中断)
  2. 五种原语的执行步骤
  3. 阻塞和唤醒的关系(阻塞主动,唤醒被动)
  4. fork()的工作原理(子进程复制父进程)

思考题#

  1. 为什么原语要用关中断/开中断来保证原子性?
  2. 进程被阻塞后,是谁把它唤醒的?
  3. fork()之后,父进程和子进程的执行顺序是怎样的?

上一篇OS笔记(二):进程的状态与转换 下一篇OS笔记(四):进程通信

分享

如果这篇文章对你有帮助,欢迎分享给更多人!

OS笔记(三):进程控制
https://emilia520.icu/posts/os-214进程控制/
作者
火花花
发布于
2026-06-05
许可协议
CC BY-NC-SA 4.0

部分信息可能已经过时

目录