操作系统将所有进程记录好,按照合理的次序推进(资源分配、进程调度),就是多进程图像。
多进程图像在整个操作系统的生命周期中存在,是操作系统最核心的图像。
main.c中的main函数的最后if(!fork()) {init();},创建了子进程,在子进程中打开了shell。
int main(int argc, char* argv[]) {
while(1) {
scanf("%s", cmd);
if(!fork()) {
exec(cmd);
wait();
}
}
}
多进程如何组织?
操作系统感知进程与组织进程全部依赖于PCB。任一时刻,操作系统只有1个正在执行的进程,即运行态的进程,其PCB信息存在于CPU中。
操作系统维护了1个就绪队列,n个等待队列(例如磁盘等待队列、打印机等待队列等)。就绪队列的元素是处于就绪态的进程的PCB结构体,等待队列的元素是处于阻塞态的进程的PCB结构体。
多进程如何交替?
// 伪代码
cur_pcb.state = 'W'; // 启动磁盘读写,把自己的状态置为阻塞态
disk_wait_queue.append(cur_pcb); // 将cur_pcb放入磁盘等待队列
schedule();
schedule() {
new_pcb = get_next(ready_queue); // 从就绪队列拿出一个new_pcb,进程调度
switch_to(cur_pcb, new_pcb); // 切换到new_pcb,保存现场
}
switch_to(cur_pcb, new_pcb) {
cur_pcb.ax = cpu.ax;
cur_pcb.bx = cpu.bx;
...
cur_pcb.cs = cpu.cs;
cpu.ax = new_pcb.ax;
cpu.bx = new_pcb.bx;
...
cpu.cs = new_pcb.cs;
}
多进程如何影响?
考虑下面代码带来的问题。
; 进程1 ; 进程2
mov [100], ax 100: ...
进程1会不会修改到进程2代码所在的内存空间?答案是不会,每个进程有一个自己的地址空间,100是逻辑地址会映射到一个物理地址。进程管理带动内存管理。
多进程如何合作?
考虑两个进程向待打印队列中添加文件,如果没有适当的同步机制,那么在进程切换时,会导致打印队列中文件的错乱。进程管理还带来了进程同步的问题。
如何形成多进程图像?
①读写PCB,OS中最重要的结构,贯穿始终;②操作寄存器完成切换;③书写进程调度程序;④要有进程同步与合作;⑤要有逻辑地址到物理地址的映射。