In [1]:
from mosaic import *
OS2023(15)
15. 操作系统上的进程¶
Changelog & 反馈
- 上次课没准备 debug 代码,属于失败了 (今天补上)
- 期中测验:下周二 (4.11) 上午 10:10-12:00
- L2 已经发布,但依赖于 L1
- 建议大家留一个 “一把大锁” 的 baseline L1
- L1 的测试用例其实不强,你有 bug 可能是逮不到的
背景回顾:有关状态机、并发和中断的讨论给我们真正理解操作系统奠定了基础,现在我们正式进入操作系统和应用程序的 “边界” 了。让我们把视角回到单线程应用程序,即 “执行计算指令和系统调用指令的状态机”,开始对操作系统和进程的讨论。
本讲内容:操作系统上的进程
- 线程、进程和操作系统
- UNIX/Linux 进程管理 API
In [2]:
slideshow('15.1')
In [3]:
demo('thread-os', 'c/thread-os-singlecpu')
In [4]:
demo('minimal', 'i/minimal')
实际上,在 UNIX/Linux 系统内核完成初始化后,只有一个 init 进程被启动,从此以后,操作系统内核就化身为了一个事件驱动的程序、状态机的管理者,仅在中断和系统调用发生时开始执行。我们看到的 “花花世界”,完全是由进程 (也就是状态机管理) 管理的 API (系统调用) 创建出来的。
In [5]:
slideshow('15.2')
In [6]:
demo('fork-demo', 'v/fork-demo.c')
In [7]:
model('m/fork-demo.py', check=True)
In [8]:
demo('fork-printf', 'v/fork-printf.c')
In [9]:
model('m/fork-printf.py', check=True)
In [10]:
model('m/fork-printf1.py', check=True)
In [11]:
slideshow('15.3')
In [12]:
demo('execve-demo', 'v/execve-demo.c')
In [13]:
slideshow('15.4')
In [14]:
demo('exit-demo', 'v/exit-demo.c')
Take-away Messages¶
因为 “程序 = 状态机”,操作系统上进程 (运行的程序) 管理的 API 很自然地就是状态机的管理。在 UNIX/Linux 世界中,这是通过以下三个最重要的系统调用实现的:
- fork: 对当前状态机状态进行完整复制
- execve: 将当前状态机状态重置为某个可执行文件描述的状态机
- exit: 销毁当前状态机
在对这个概念有了绝对正确且绝对严谨的理解后,操作系统也就显得不那么神秘了。
课后习题/编程作业¶
1. 阅读材料¶
教科书 Operating Systems: Three Easy Pieces:
- 第 3 章 - Dialogue
- 第 4 章 - Processes
- 第 5 章 - Process API
2. 编程实践¶
在你的机器上重现课堂代码上的结果,并确保你对代码的行为有清楚的理解,之后就可以在手册的帮助下完成实验。