Chapter 4 Abstraction: Processes

第 4 章 抽象:进程

进程就是运行中的程序。程序本身是没有生命周期的,它只是存在磁盘上面的一些指令(也可能是一些静态数据)。

操作系统通过虚拟化(virtualizing)CPU来提供这种假象(提供无数个CPU)。

关键技术点:

  • 低级机制

    • mechanism,低级方法或协议,实现了所需功能

    • context switch,上下文切换,停止运行一个程序,并运行另一个程序

    • 分时机制

  • 高级智能

    • policy,策略,操作系统内做出某种决定的算法

    • scheduling policy,调度策略,综合考量(历史信息,工作负载知识,性能指标)

1. 抽象:进程概念

process 进程。

1.1. 需要理解以下内容:

机器状态 machine state

程序在运行时可以读取或更新的内容

内存

进程可以访问的内润,地址空间,address space

寄存器

许多指令明确地读取或更新寄存器

特殊的寄存器:

  • 程序计数器 Program Counter,PC

    • 有时称为 指令指针,Instruction Pointer,IP

    • 告诉我们程序将执行哪个指令

  • 栈指针 stack pointer 和 帧指针 frame pointer

    • 用于管理函数参数栈、局部变量和返回地址

分离 policy and mechism:modularity 模块化

  • 机制 mechanism 解决 how 的问题

  • 策略 policy 解决 which 的问题

2. 进程 API

进程的接口,真正的 API 会在后面学习...

创建 create

创建新进程

销毁 destroy

强制销毁进程

等待 wait

等待进程停止...

其他控制 miscellaneous control

暂停进程 或者 恢复运行 等等

状态 status

获取进程信息:运行了多久?处于什么状态?

3. 进程创建:更多细节

程序 - 进程 的转变...

3.1. 第一步:代码 + 静态数据 加载到 内存

load to disk(early) or SSD(now)

早期:eagerly

运行程序之前全部完成

现代:lazily

在程序执行期间需要加载的代码或数据片段才会加载

3.2. 第二步:为程序的运行时栈 分配 一些内存

(run-time stack 或 stack)

举例:在 C 语言中会使用栈来存放局部变量,函数参数和返回地址...

操作系统分配这些内存,并提供给进程...

3.3. 第三步:可能为程序的堆分配一些内存

heap...

在 C 程序中,堆用于显式请求的动态内存分配数据。

malloc() 请求空间,free() 释放空间

数据结构

链表、散列表、树 and other...也需要堆

3.4. 第四步:执行一些其他初始化任务

特别是与 I/O 输入/输出 相关的任务

UNIX 系统

默认打开 3 个文件描述符 file descriptor 用于 标准输入、输出和错误

3.5. OS 现在 终于 为程序执行搭好了舞台

他还有最后一项任务

启动程序

在入口处运行,main()

4. 进程状态

简而言之,进程可以处于以下 3 种状态之一

4.1. 运行 running

进程正在处理器上运行,正在执行指令

4.2. 就绪 ready

程序已准备好运行,但处于某种原因,操作系统选择不在此时执行

4.3. 阻塞 blocked

一个进程执行了某种操作,直到发生其他时间时才会准备运行

一个例子:当进程向磁盘发起I/O请求时,它会被阻塞,因此其他进程可以使用处理器....

4.4. 操作系统的决定

需要决定如何进行调度,一个程序就绪时要不要立即执行?阻塞时候等还是不等?所有一切都需要一个好的 policy...

5. 数据结构

操作系统和其他程序一样,有一些关键的数据结构来跟踪各种相关的信息...

5.1. 例子:为了跟踪每个进程的状态

  • OS 会为所有就虚的进程保留某种进程列表,以及跟踪当前正在运行的进程和一些附加信息...

  • OS 还必须以某种方式跟踪被阻塞的进程

  • 当 I/O 时间完成时,OS 应确保唤醒正确的进程,让它准备好再次运行

5.2. xv6 内核的 proc 结构

#include <wtypes.h>

#define ulong ULONG
#define uint UINT
#define NOFILE 10

// the registers xv6 will save and restore
// to stop and subsequently restrat a process
struct context
{
  int eip;
  int esp;
  int ebx;
  int ecx;
  int edx;
  int esi;
  int edi;
  int ebp;
};

// the different states a process can be in
enum proc_state
{
  UNUSED,
  EMBRYO,
  SLEEPING,
  RUNNABLE,
  RUNNING,
  ZOMBIE
};

// the information xv6 tracks about a process
// including its register context and state
struct proc
{
  char *mem;                  // Start of process memory
  uint sz;                    // Size of process memory
  char *kstack;               // Bottom of kernel stack for this process
  enum proc_state state;      // Process state
  int pid;                    // Process ID
  struct proc *parent;        // Parent process
  void *chan;                 // If non-zero, sleeping on chan
  int killed;                 // If non-zero, have been killed
  struct file *ofile[NOFILE]; // Open files
  struct inode *cwd;          // Current directory
  struct context context;     // Switch here to run process
  struct trapframe *tf;       // Trap frame for the current interrupt
};

代码中除了 running、ready and blocked 之外,还有一些状态

  1. System 一开始会有一个 initial 状态 表示进程在创建时处于的状态

  2. final 状态 使得进程可以处于已退出但尚未清理的最终状态 僵尸状态

5.3. 补充

数据结构 - 进程列表

process list

6. 作业:模拟作业

6.1. ./process-run.py -l 5:100,5:100

Run process-run.py with the following flags: -l 5:100,5:100. What should the CPU utilization be (e.g., the percent of time the CPU is in use?) Why do you know this? Use the -c and -p flags to see if you were right.

6.2. ./process-run.py -l 4:100,1:0

Now run with these flags: ./process-run.py -l 4:100,1:0. These flags specify one process with 4 instructions (all to use the CPU), and one that simply issues an I/O and waits for it to be done. How long does it take to complete both processes? Use -c and -p to find out if you were right.

root@LAPTOP-GT06V0GS:/mnt/d/CSLab/osTEP/chapter4/homework# ./process-run.py -l 4:100,1:0 -c -p
Time        PID: 0        PID: 1           CPU           IOs
  1        RUN:cpu         READY             1
  2        RUN:cpu         READY             1
  3        RUN:cpu         READY             1
  4        RUN:cpu         READY             1
  5           DONE        RUN:io             1
  6           DONE       BLOCKED                           1
  7           DONE       BLOCKED                           1
  8           DONE       BLOCKED                           1
  9           DONE       BLOCKED                           1
 10           DONE       BLOCKED                           1
 11*          DONE   RUN:io_done             1

Stats: Total Time 11
Stats: CPU Busy 6 (54.55%)
Stats: IO Busy  5 (45.45%)

PID 0 先全程占用 CPU,随后处理 PID 1,发出 IO 请求后 CPU 空闲...占用 IO。可以看到 CPU 占用率仅 54.55%...

所以能不能先处理 PID 1 然后在 1 Blocked 的时候 处理 PID 0...

6.3. ./process-run.py -l 1:0,4:100. -c -p

Switch the order of the processes: -l 1:0,4:100. What happens now? Does switching the order matter? Why? (As always, use -c and -p to see if you were right)

root@LAPTOP-GT06V0GS:/mnt/d/CSLab/osTEP/chapter4/homework# ./process-run.py -l 1:0,4:100. -c -p
Time        PID: 0        PID: 1           CPU           IOs
  1         RUN:io         READY             1
  2        BLOCKED       RUN:cpu             1             1
  3        BLOCKED       RUN:cpu             1             1
  4        BLOCKED       RUN:cpu             1             1
  5        BLOCKED       RUN:cpu             1             1
  6        BLOCKED          DONE                           1
  7*   RUN:io_done          DONE             1

Stats: Total Time 7
Stats: CPU Busy 6 (85.71%)
Stats: IO Busy  5 (71.43%)

交换处理顺序后可以看到,CPU 占用率大大增加...提高了运行效率...

6.4. ./process-run.py -l 1:0,4:100 -c -S SWITCH ON END

We’ll now explore some of the other flags. One important flag is -S, which determines how the system reacts when a process issues an I/O. With the flag set to SWITCH ON END, the system will NOT switch to another process while one is doing I/O, instead waiting until the process is completely finished. What happens when you run the following two processes (-l 1:0,4:100 -c -S SWITCH_ON_END), one doing I/O and the other doing CPU work?

root@LAPTOP-GT06V0GS:/mnt/d/CSLab/osTEP/chapter4/homework# ./process-run.py -l 1:0,4:100 -c -S SWITCH_ON_END -p
Time        PID: 0        PID: 1           CPU           IOs
  1         RUN:io         READY             1
  2        BLOCKED         READY                           1
  3        BLOCKED         READY                           1
  4        BLOCKED         READY                           1
  5        BLOCKED         READY                           1
  6        BLOCKED         READY                           1
  7*   RUN:io_done         READY             1
  8           DONE       RUN:cpu             1
  9           DONE       RUN:cpu             1
 10           DONE       RUN:cpu             1
 11           DONE       RUN:cpu             1

Stats: Total Time 11
Stats: CPU Busy 6 (54.55%)
Stats: IO Busy  5 (45.45%)

加上 -S 之后,在 PID 0 被 blocked 之后,CPU 并不会处理 PID 1,而是等待 PID 0 完成...可以看到 CPU 效率也会因此降低...

6.5. ./process-run.py -l 1:0,4:100 -c -S SWITCH_ON_IO

Now, run the same processes, but with the switching behavior set to switch to another process whenever one is WAITING for I/O (-l 1:0,4:100 -c -S SWITCH_ON_IO). What happens now? Use -c and -p to confirm that you are right.

root@LAPTOP-GT06V0GS:/mnt/d/CSLab/osTEP/chapter4/homework# ./process-run.py -l 1:0,4:100 -c -S SWITCH_ON_IO -p
Time        PID: 0        PID: 1           CPU           IOs
  1         RUN:io         READY             1
  2        BLOCKED       RUN:cpu             1             1
  3        BLOCKED       RUN:cpu             1             1
  4        BLOCKED       RUN:cpu             1             1
  5        BLOCKED       RUN:cpu             1             1
  6        BLOCKED          DONE                           1
  7*   RUN:io_done          DONE             1

Stats: Total Time 7
Stats: CPU Busy 6 (85.71%)
Stats: IO Busy  5 (71.43%)

这时候其实有点像 Q 3 的那个,应该是默认的设置...不会等待,而是哪个空处理哪个...

6.6. ./process-run.py -l 3:0,5:100,5:100,5:100 -S SWITCH_ON_IO -c -p -I IO_RUN_LATER

One other important behavior is what to do when an I/O completes. With -I IO RUN LATER, when an I/O completes, the process that issued it is not necessarily run right away; rather, whatever was running at the time keeps running. What happens when you run this combination of processes? (./process-run.py -l 3:0,5:100,5:100,5:100 -S SWITCH_ON_IO -c -p -I IO_RUN_LATER) Are system resources being effectively utilized?

root@LAPTOP-GT06V0GS:/mnt/d/CSLab/osTEP/chapter4/homework# ./process-run.py -l 3:0,5:100,5:100,5:100 -S SWITCH_ON_IO -c -p -I IO_RUN_LATER
Time        PID: 0        PID: 1        PID: 2        PID: 3           CPU           IOs
  1         RUN:io         READY         READY         READY             1        
  2        BLOCKED       RUN:cpu         READY         READY             1             1
  3        BLOCKED       RUN:cpu         READY         READY             1             1
  4        BLOCKED       RUN:cpu         READY         READY             1             1
  5        BLOCKED       RUN:cpu         READY         READY             1             1
  6        BLOCKED       RUN:cpu         READY         READY             1             1
  7*         READY          DONE       RUN:cpu         READY             1        
  8          READY          DONE       RUN:cpu         READY             1        
  9          READY          DONE       RUN:cpu         READY             1        
 10          READY          DONE       RUN:cpu         READY             1        
 11          READY          DONE       RUN:cpu         READY             1        
 12          READY          DONE          DONE       RUN:cpu             1        
 13          READY          DONE          DONE       RUN:cpu             1        
 14          READY          DONE          DONE       RUN:cpu             1        
 15          READY          DONE          DONE       RUN:cpu             1        
 16          READY          DONE          DONE       RUN:cpu             1        
 17    RUN:io_done          DONE          DONE          DONE             1        
 18         RUN:io          DONE          DONE          DONE             1        
 19        BLOCKED          DONE          DONE          DONE                           1
 20        BLOCKED          DONE          DONE          DONE                           1
 21        BLOCKED          DONE          DONE          DONE                           1
 22        BLOCKED          DONE          DONE          DONE                           1
 23        BLOCKED          DONE          DONE          DONE                           1
 24*   RUN:io_done          DONE          DONE          DONE             1        
 25         RUN:io          DONE          DONE          DONE             1        
 26        BLOCKED          DONE          DONE          DONE                           1
 27        BLOCKED          DONE          DONE          DONE                           1
 28        BLOCKED          DONE          DONE          DONE                           1
 29        BLOCKED          DONE          DONE          DONE                           1
 30        BLOCKED          DONE          DONE          DONE                           1
 31*   RUN:io_done          DONE          DONE          DONE             1        

Stats: Total Time 31
Stats: CPU Busy 21 (67.74%)
Stats: IO Busy  15 (48.39%)

当一个 process 的 io block 结束之后,CPU 不会马上继续处理这个 process 而是继续往下执行...最后才会回来执行,这有时候会拖慢 CPU 的效率...

6.7. ./process-run.py -l 3:0,5:100,5:100,5:100 -S SWITCH_ON_IO -c -p -I IO_RUN_IMMEDIATE

Now run the same processes, but with -I IO RUN_IMMEDIATE set, which immediately runs the process that issued the I/O. How does this behavior differ? Why might running a process that just completed an I/O again be a good idea?

root@LAPTOP-GT06V0GS:/mnt/d/CSLab/osTEP/chapter4/homework# ./process-run.py -l 3:0,5:100,5:100,5:100 -S SWITCH_ON_IO -c -p -I IO_RUN_IMMEDIATE
Time        PID: 0        PID: 1        PID: 2        PID: 3           CPU           IOs
  1         RUN:io         READY         READY         READY             1        
  2        BLOCKED       RUN:cpu         READY         READY             1             1
  3        BLOCKED       RUN:cpu         READY         READY             1             1
  4        BLOCKED       RUN:cpu         READY         READY             1             1
  5        BLOCKED       RUN:cpu         READY         READY             1             1
  6        BLOCKED       RUN:cpu         READY         READY             1             1
  7*   RUN:io_done          DONE         READY         READY             1        
  8         RUN:io          DONE         READY         READY             1        
  9        BLOCKED          DONE       RUN:cpu         READY             1             1
 10        BLOCKED          DONE       RUN:cpu         READY             1             1
 11        BLOCKED          DONE       RUN:cpu         READY             1             1
 12        BLOCKED          DONE       RUN:cpu         READY             1             1
 13        BLOCKED          DONE       RUN:cpu         READY             1             1
 14*   RUN:io_done          DONE          DONE         READY             1        
 15         RUN:io          DONE          DONE         READY             1        
 16        BLOCKED          DONE          DONE       RUN:cpu             1             1
 17        BLOCKED          DONE          DONE       RUN:cpu             1             1
 18        BLOCKED          DONE          DONE       RUN:cpu             1             1
 19        BLOCKED          DONE          DONE       RUN:cpu             1             1
 20        BLOCKED          DONE          DONE       RUN:cpu             1             1
 21*   RUN:io_done          DONE          DONE          DONE             1        

Stats: Total Time 21
Stats: CPU Busy 21 (100.00%)
Stats: IO Busy  15 (71.43%)

当把参数设置为 immediate 之后,process 会在 block 之后立即被 CPU 处理...为什么这是一个好主意?

在操作系统中,将进程在阻塞(block)之后立即被CPU处理的调度策略称为“立即调度”(Immediate Scheduling)。

这种策略通常用于需要快速响应的场景,尤其是在实时系统中。

  1. 提高响应速度

    1. quick response

    2. reduce wait

  2. 增强系统的实时性

    1. reduce jitter

      1. 抖动是指任务执行时间的不稳定性。立即调度可以减少任务在就绪队列中的等待时间,从而降低抖动,提高系统的稳定性。

  3. 提高系统吞吐量

    1. increse CPU efficiency

  4. 提高系统的公平性

    1. avoid hungry phenomenen

    2. dynamic adjust prior

  5. 适应动态变化的系统需求

6.8. ./process-run.py -s 1 -l 3:50,3:50 or -s 2 -l 3:50,3:50 or -s 3 -l 3:50,3:50 -c -p

Now run with some randomly generated processes using flags -s 1 -l 3:50,3:50 or -s 2 -l 3:50,3:50 or -s 3 -l 3:50, 3:50. See if you can predict how the trace will turn out. What happens when you use the flag -I IO_RUN_IMMEDIATE versus that flag -I IO_ RUN_LATER? What happens when you use the flag -S SWITCH_ON_IO versus -S SWITCH_ON_END?

无 -I -S 参数版本

root@LAPTOP-GT06V0GS:/mnt/d/CSLab/osTEP/chapter4/homework# ./process-run.py -s 1 -l 3:50,3:50 or -s 2 -l 3:50,3:50 or -s 3 -l 3:50,3:50 -c -p
Time        PID: 0        PID: 1           CPU           IOs
  1        RUN:cpu         READY             1
  2         RUN:io         READY             1
  3        BLOCKED        RUN:io             1             1
  4        BLOCKED       BLOCKED                           2
  5        BLOCKED       BLOCKED                           2
  6        BLOCKED       BLOCKED                           2
  7        BLOCKED       BLOCKED                           2
  8*   RUN:io_done       BLOCKED             1             1
  9*       RUN:cpu         READY             1
 10           DONE   RUN:io_done             1
 11           DONE        RUN:io             1
 12           DONE       BLOCKED                           1
 13           DONE       BLOCKED                           1
 14           DONE       BLOCKED                           1
 15           DONE       BLOCKED                           1
 16           DONE       BLOCKED                           1
 17*          DONE   RUN:io_done             1
 18           DONE       RUN:cpu             1

Stats: Total Time 18
Stats: CPU Busy 9 (50.00%)
Stats: IO Busy  11 (61.11%)

程序行为应该是两个都需要 io 的进程...

-I IO_RUN_IMMEDIATE

root@LAPTOP-GT06V0GS:/mnt/d/CSLab/osTEP/chapter4/homework# ./process-run.py -s 1 -l 3:50,3:50 or -s 2 -l 3:50,3:50 or -s 3 -l 3:50,3:50 -I IO_RUN_IMMEDIATE -c -p
Time        PID: 0        PID: 1           CPU           IOs
  1        RUN:cpu         READY             1
  2         RUN:io         READY             1
  3        BLOCKED        RUN:io             1             1
  4        BLOCKED       BLOCKED                           2
  5        BLOCKED       BLOCKED                           2
  6        BLOCKED       BLOCKED                           2
  7        BLOCKED       BLOCKED                           2
  8*   RUN:io_done       BLOCKED             1             1
  9*         READY   RUN:io_done             1
 10          READY        RUN:io             1
 11        RUN:cpu       BLOCKED             1             1
 12           DONE       BLOCKED                           1
 13           DONE       BLOCKED                           1
 14           DONE       BLOCKED                           1
 15           DONE       BLOCKED                           1
 16*          DONE   RUN:io_done             1
 17           DONE       RUN:cpu             1

Stats: Total Time 17
Stats: CPU Busy 9 (52.94%)
Stats: IO Busy  11 (64.71%)

-I IO_ RUN_LATER

和无参数的时候一样啊,证明默认应该是继续执行,而不是回头?

root@LAPTOP-GT06V0GS:/mnt/d/CSLab/osTEP/chapter4/homework# ./process-run.py -s 1 -l 3:50,3:50 or -s 2 -l 3:50,3:50 or -s 3 -l 3:50,3:50 -I IO_RUN_LATER -c -p
Time        PID: 0        PID: 1           CPU           IOs
  1        RUN:cpu         READY             1
  2         RUN:io         READY             1
  3        BLOCKED        RUN:io             1             1
  4        BLOCKED       BLOCKED                           2
  5        BLOCKED       BLOCKED                           2
  6        BLOCKED       BLOCKED                           2
  7        BLOCKED       BLOCKED                           2
  8*   RUN:io_done       BLOCKED             1             1
  9*       RUN:cpu         READY             1
 10           DONE   RUN:io_done             1
 11           DONE        RUN:io             1
 12           DONE       BLOCKED                           1
 13           DONE       BLOCKED                           1
 14           DONE       BLOCKED                           1
 15           DONE       BLOCKED                           1
 16           DONE       BLOCKED                           1
 17*          DONE   RUN:io_done             1
 18           DONE       RUN:cpu             1

Stats: Total Time 18
Stats: CPU Busy 9 (50.00%)
Stats: IO Busy  11 (61.11%)

-S SWITCH_ON_IO

root@LAPTOP-GT06V0GS:/mnt/d/CSLab/osTEP/chapter4/homework# ./process-run.py -s 1 -l 3:50,3:50 or -s 2 -l 3:50,3:50 or -s 3 -l 3:50,3:50 -S SWITCH_ON_IO -c -p
Time        PID: 0        PID: 1           CPU           IOs
  1        RUN:cpu         READY             1
  2         RUN:io         READY             1
  3        BLOCKED        RUN:io             1             1
  4        BLOCKED       BLOCKED                           2
  5        BLOCKED       BLOCKED                           2
  6        BLOCKED       BLOCKED                           2
  7        BLOCKED       BLOCKED                           2
  8*   RUN:io_done       BLOCKED             1             1
  9*       RUN:cpu         READY             1
 10           DONE   RUN:io_done             1
 11           DONE        RUN:io             1
 12           DONE       BLOCKED                           1
 13           DONE       BLOCKED                           1
 14           DONE       BLOCKED                           1
 15           DONE       BLOCKED                           1
 16           DONE       BLOCKED                           1
 17*          DONE   RUN:io_done             1
 18           DONE       RUN:cpu             1

Stats: Total Time 18
Stats: CPU Busy 9 (50.00%)
Stats: IO Busy  11 (61.11%)

-S SWITCH_ON_END

root@LAPTOP-GT06V0GS:/mnt/d/CSLab/osTEP/chapter4/homework# ./process-run.py -s 1 -l 3:50,3:50 or -s 2 -l 3:50,3:50 or -s 3 -l 3:50,3:50 -S SWITCH_ON_END -c -p
Time        PID: 0        PID: 1           CPU           IOs
  1        RUN:cpu         READY             1
  2         RUN:io         READY             1
  3        BLOCKED         READY                           1
  4        BLOCKED         READY                           1
  5        BLOCKED         READY                           1
  6        BLOCKED         READY                           1
  7        BLOCKED         READY                           1
  8*   RUN:io_done         READY             1
  9        RUN:cpu         READY             1
 10           DONE        RUN:io             1
 11           DONE       BLOCKED                           1
 12           DONE       BLOCKED                           1
 13           DONE       BLOCKED                           1
 14           DONE       BLOCKED                           1
 15           DONE       BLOCKED                           1
 16*          DONE   RUN:io_done             1
 17           DONE        RUN:io             1
 18           DONE       BLOCKED                           1
 19           DONE       BLOCKED                           1
 20           DONE       BLOCKED                           1
 21           DONE       BLOCKED                           1
 22           DONE       BLOCKED                           1
 23*          DONE   RUN:io_done             1
 24           DONE       RUN:cpu             1

Stats: Total Time 24
Stats: CPU Busy 9 (37.50%)
Stats: IO Busy  15 (62.50%)

总结

总觉得有点乱啊...

找AI帮忙总结一下

  1. -I IO_RUN_IMMEDIATE

    1. 当一个进程完成 I/O 操作后,操作系统立即切换到该进程,让其继续运行。

    2. 进程完成 I/O 操作后,操作系统会立即将其状态设置为 READY ,并立即切换到该进程。

    3. 如果此时 CPU 是空闲的,该进程会立即获得 CPU 资源并继续执行。

    4. 如果 CPU 正在运行其他进程,操作系统会中断当前运行的进程,切换到完成 I/O 的进程。

  2. -I IO_RUN_LATER

    1. 当一个进程完成 I/O 操作后,操作系统不会立即切换到该进程,而是将其放入就绪队列,等待调度器调度。

    2. 进程完成 I/O 操作后,操作系统将其状态设置为 READY ,并将其放入就绪队列。

    3. 调度器会在合适的时机选择该进程运行,而不是立即切换。

  3. -S SWITCH_ON_IO

    1. 当一个进程发起 I/O 操作时,操作系统立即切换到另一个进程。

    2. 进程发起 I/O 操作时,操作系统将其状态设置为 WAIT ,并立即切换到另一个就绪的进程。

    3. 这种切换发生在 I/O 操作开始时,而不是 I/O 操作完成时。

  4. -S SWITCH_ON_END

    1. 当一个进程完成其所有操作后,操作系统才切换到另一个进程。

    2. 进程在完成其所有操作(包括 I/O 和 CPU 操作)后,操作系统才切换到另一个就绪的进程。

    3. 这种切换发生在进程结束时,而不是在 I/O 操作开始时。

总的来说是这样,-I IO_RUN_IMMEDIATE 在 IO 结束后会立即切换回去...LATER则不然。-S SWITCH_ON_IO会在发起IO时,换成别的线程,END则是等待...

各自有优点吧...CPU效率最大化应该是-I IO_RUN_IMMEDIATE + -S SWITCH_ON_IO

但这样不总是对的,考虑的还有上下文切换的成本之类的。

实际应用中的选择

  • CPU 密集型任务:使用 -S SWITCH_ON_END ,减少上下文切换开销,提高 CPU 利用率。

  • I/O 密集型任务:使用 -S SWITCH_ON_IO ,避免 I/O 阻塞,提高系统吞吐量。

  • 需要快速响应 I/O 完成的场景:使用 -I IO_RUN_IMMEDIATE ,减少等待时间,提高响应速度。

  • 需要减少上下文切换开销的场景:使用 -I IO_RUN_LATER ,提高系统吞吐量。

CPU效率最高 同时 IO效率最高 (在这道题)...

root@LAPTOP-GT06V0GS:/mnt/d/CSLab/osTEP/chapter4/homework# ./process-run.py -s 1 -l 3:50,3:50 or -s 2 -l 3:50,3:50 or -s 3 -l 3:50,3:50 -I IO_RUN_IMMEDIATE -S SWITCH_ON_IO -c -p
Time        PID: 0        PID: 1           CPU           IOs
  1        RUN:cpu         READY             1
  2         RUN:io         READY             1
  3        BLOCKED        RUN:io             1             1
  4        BLOCKED       BLOCKED                           2
  5        BLOCKED       BLOCKED                           2
  6        BLOCKED       BLOCKED                           2
  7        BLOCKED       BLOCKED                           2
  8*   RUN:io_done       BLOCKED             1             1
  9*         READY   RUN:io_done             1
 10          READY        RUN:io             1
 11        RUN:cpu       BLOCKED             1             1
 12           DONE       BLOCKED                           1
 13           DONE       BLOCKED                           1
 14           DONE       BLOCKED                           1
 15           DONE       BLOCKED                           1
 16*          DONE   RUN:io_done             1
 17           DONE       RUN:cpu             1

Stats: Total Time 17
Stats: CPU Busy 9 (52.94%)
Stats: IO Busy  11 (64.71%)

Last updated