1. 进程切换

又称 上下文切换

  1. 暂停当前运行进程,从运行状态变成其他状态
  2. 调度另一个进程从就绪变成运行

要求:

  1. 切换前,保存进程上下文
  2. 切换后,恢复进程上下文
  3. 快速切换

由汇编实现,因为需要速度快

1

PCB里记录:内核的进程状态
内核将相同状态的进程的PCB放置在同一队列。

2. 进程创建

Windows进程创建API:CreateProcess(filename)

Linux进程创建API:fork/exec(execute)

调用fork()后的状态变化(exec调用新进程)

2

3

fork()使用示例

4

创建成功后,放入就绪队列中。

创建一个内核线程

5

fork()的实际开销

子进程复制父进程的内存和CPU寄存器到子进程里,开销巨大

因为99%情况下,在调用fork()后会调用exec()

所以在fork()中的内存复制是不必要的

这时候!

我们使用vfork()

采用Copy on Write(COW技术,也叫 写时复用 技术

3. 进程加载

允许进程“加载”一个完全不同的程序,并从main开始执行(即_start)

允许进程加载时指定启动参数(argc, argv)

代码段,堆,栈等完全会被重写。

ucore中exec()实现

  1. sys_exec 获取参数
  2. do_execve 加载,核心
  3. load_icode 识别可执行文件,核心

4. 进程的等待与退出

父子进程进行资源的回收

wait()系统调用用于父进程等待子进程的结束

  1. 子进程结束时通过exit()向父进程返回一个值
  2. 父进程通过wait()接受并处理返回值

功能:

  1. 如果有子进程存活,父进程进入等待状态
  2. 子进程调用exit(),父进程唤醒,将exit()返回值作为父进程wait()的返回值
  3. 有僵尸子进程等待时,父进程wait()立刻返回其中一个值
  4. 无子进程存活,wait()直接返回

进程的有序终止exit()

  1. 调用exit(),完成进程资源回收

功能:

  1. 将调用参数作为进程的结果
  2. 关闭所有打开的文件等占用资源
  3. 释放内存
  4. 释放大部分进程相关的内核数据结构
  5. 检查父进程是否存活
    • 存活:保留结果值直到父进程需要它,进入僵尸状态(zombie/defunct)状态
    • 没有存辉:释放所有数据结构,进程结果

子进程在exit()检查父进程
父进程在wait()检查子进程

进程控制进程状态 关系

6

评论