Overview
这个程序,名为 process-run.py,允许你观察一个进程在 CPU 上运行时其状态如何变化。正如章节中描述的,进程可以处于几个不同的状态:
RUNNING - 进程目前正在使用 CPU。
READY - 进程现在可以使用 CPU,但(遗憾的是)有其他进程正在使用。
BLOCKED - 进程正在等待 I/O(输入/输出)操作完成。(例如,它向磁盘发出了一个请求)
DONE - 进程已经执行完毕。
在这项作业中,我们将观察程序运行时这些进程状态如何变化,从而更好地了解这些机制是如何工作的。
要运行程序并获取其选项,请执行以下操作:
prompt> ./process-run.py -h
如果上面的命令不起作用,你可以在命令前加上 python
,像这样:
prompt> python process-run.py -h
Usage: process-run.py [options]
Options:
-h, --help 显示此帮助信息并退出
-s SEED, --seed=SEED 随机种子
-l PROCESS_LIST, --processlist=PROCESS_LIST
一个用逗号分隔的进程列表来运行,形式为 X1:Y1,X2:Y2,... 其中 X 是进程应该运行的指令数,Y 是指令使用 CPU 或发出 I/O 的几率(从 0 到 100)
-L IO_LENGTH, --iolength=IO_LENGTH
一个 I/O 操作需要多长时间
-S PROCESS_SWITCH_BEHAVIOR, --switch=PROCESS_SWITCH_BEHAVIOR
何时在进程间切换:SWITCH_ON_IO(在 I/O 时切换),SWITCH_ON_END(在结束时切换)
-I IO_DONE_BEHAVIOR, --iodone=IO_DONE_BEHAVIOR
I/O 结束时的行为类型:IO_RUN_LATER(稍后运行),IO_RUN_IMMEDIATE(立即运行)
-c 为我计算答案
-p, --printstats 在结束时打印统计信息;仅与 -c 标志一起使用(否则不打印统计信息)
要理解的最重要的选项是 PROCESS_LIST(由 -l 或 --processlist 标志指定),它精确地指定了每个运行的程序(或“进程”)将执行什么操作。一个进程由指令组成,每个指令只能执行以下两种操作之一:
- 使用 CPU
- 发出 I/O 请求(并等待其完成)
当一个进程仅使用 CPU(并不执行任何 I/O)时,它应该在 CPU 上运行(RUNNING)和准备运行(READY)之间交替。例如,以下是一个简单的运行示例,只有一个程序在运行,并且该程序仅使用 CPU(不执行 I/O):
prompt> ./process-run.py -l 5:100
Produce a trace of what would happen when you run these processes:
Process 0
cpu
cpu
cpu
cpu
cpu
Important behaviors:
在您描述的模拟环境中,系统的进程切换通常发生在当前进程完成其所有指令或发出一个 I/O 请求时。当进程发出 I/O 请求后,它将不再占用 CPU,而是进入等待 I/O 完成的状态。此时,系统可能会切换到其他就绪(READY)状态的进程来执行。
prompt>
当您指定进程为 “5:100” 时,这意味着该进程将由 5 个指令组成,并且每个指令有 100% 的几率是 CPU 指令(即不执行任何 I/O 操作)。
要使用 -c
标志来查看进程的行为和结果,您可以运行如下命令:
python process-run.py -l 5:100 -c
这个命令会启动模拟,让进程执行 5 个 CPU 指令,并且因为每个指令都是 CPU 指令,所以进程不会发出任何 I/O 请求。使用 -c
标志会让模拟程序为您计算并显示结果。
prompt> ./process-run.py -l 5:100 -c
Time PID: 0 CPU IOs
1 RUN:cpu 1
2 RUN:cpu 1
3 RUN:cpu 1
4 RUN:cpu 1
5 RUN:cpu 1
当您只运行一个 “5:100” 的进程时,结果确实不是很有趣,因为这个进程只是简单地连续执行 5 个 CPU 指令,并且没有执行任何 I/O 操作,因此它会一直占用 CPU 直到完成。
为了增加一些复杂性,我们可以同时运行两个进程,并给它们分配不同的 CPU 和 I/O 指令比例。这样,我们就可以看到进程间的切换以及 CPU 和 I/O 的使用情况。
prompt> ./process-run.py -l 5:100,5:100
Produce a trace of what would happen when you run these processes:
Process 0
cpu
cpu
cpu
cpu
cpu
Process 1
cpu
cpu
cpu
cpu
cpu
Important behaviors:
当当前进程完成或发出IO时,计划程序将切换,IO之后,发出IO的进程将稍后运行(轮到它时)
在这种情况下,运行两个不同的进程,每个进程都只使用CPU。什么
当操作系统运行它们时会发生什么?让我们来了解一下:
prompt> ./process-run.py -l 5:100,5:100 -c
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 RUN:cpu READY 1
6 DONE RUN:cpu 1
7 DONE RUN:cpu 1
8 DONE RUN:cpu 1
9 DONE RUN:cpu 1
10 DONE RUN:cpu 1
正如您在上面看到的,首先运行“进程ID”(或“PID”)为0的进程,
而进程1已准备好运行,但只是等待直到0完成。当0为
完成后,它将移动到“完成”状态,同时运行1。当1结束时,跟踪
完成。
在回答一些问题之前,让我们再看一个例子。在这个
例如,进程只是发出I/O请求。我们在这里指定I/O占用5
用标志-L完成的时间单位。
prompt> ./process-run.py -l 3:0 -L 5
Produce a trace of what would happen when you run these processes:
Process 0
io
io_done
io
io_done
io
io_done
Important behaviors:
当当前进程完成或发出IO时,系统将切换,IO之后,发出IO的进程将稍后运行(轮到它时)
你认为执行跟踪会是什么样子?让我们来了解一下:
prompt> ./process-run.py -l 3:0 -L 5 -c
Time PID: 0 CPU IOs
1 RUN:io 1
2 BLOCKED 1
3 BLOCKED 1
4 BLOCKED 1
5 BLOCKED 1
6 BLOCKED 1
7* RUN:io_done 1
8 RUN:io 1
9 BLOCKED 1
10 BLOCKED 1
11 BLOCKED 1
12 BLOCKED 1
13 BLOCKED 1
14* RUN:io_done 1
15 RUN:io 1
16 BLOCKED 1
17 BLOCKED 1
18 BLOCKED 1
19 BLOCKED 1
20 BLOCKED 1
21* RUN:io_done 1
正如您所看到的,该程序只发出三个I/O。当发出每个I/O时,
进程移动到BLOCKED状态,而设备正忙于服务
I/O,CPU空闲。
为了处理I/O的完成,还需要执行一个CPU操作。笔记
处理I/O启动和完成的单个指令不是
特别逼真,但这里只是为了简单起见。
让我们打印一些统计数据(运行与上面相同的命令,但使用-p标志)
查看一些总体行为:
Stats: Total Time 21
Stats: CPU Busy 6 (28.57%)
Stats: IO Busy 15 (71.43%)
正如您所看到的,跟踪运行了21个时钟周期,但CPU
忙碌的时间不到30%。另一方面,I/O设备
很忙。一般来说,我们希望所有设备都保持忙碌,因为
这是对资源的更好利用。
还有一些其他重要标志:
-s SEED, --seed=SEED the random seed
this gives you way to create a bunch of different jobs randomly
-L IO_LENGTH, --iolength=IO_LENGTH
this determines how long IOs take to complete (default is 5 ticks)
-S PROCESS_SWITCH_BEHAVIOR, --switch=PROCESS_SWITCH_BEHAVIOR
when to switch between processes: SWITCH_ON_IO, SWITCH_ON_END
this determines when we switch to another process:
- SWITCH_ON_IO, the system will switch when a process issues an IO
- SWITCH_ON_END, the system will only switch when the current process is done
-I IO_DONE_BEHAVIOR, --iodone=IO_DONE_BEHAVIOR
type of behavior when IO ends: IO_RUN_LATER, IO_RUN_IMMEDIATE
this determines when a process runs after it issues an IO:
- IO_RUN_IMMEDIATE: switch to this process right now
- IO_RUN_LATER: switch to this process when it is natural to
(e.g., depending on process-switching behavior)
现在请回答本章后面的问题以了解更多信息。
1.用以下标志运行程序:./process-run.py -l 5:100,5:100。CPU 利用率(CPU 使用时间的百分比)应该是多少?说明理由。然后利用 -c 和-p 标志查看你的答案是否正确。
Time PID: 0 PID: 1 CPU IOs
1 RUN:cpu READY 1
2 RUN: