通用寄存器,又称为用户可视寄存器,它们是用户程序可以访问的,用于暂存信息,在大多数处理机中,有 8~32 个通用寄存器,在RISC 结构的计算机中可超过100 个
指令计数器,其中存放了要访问的下一条指令的地址
程序状态字PSW,其中含有状态信息,如条件码、执行方式、中断屏蔽标志等
用户栈指针,指每个用户进程都有一个或若干个与之相关的系统栈,用于存放过程和系统调用参数及调用地址,栈指针指向该栈的栈顶。
进程调度信息:在 PCB中还存放一些与进程调度和进程对换有关的信息,包括
进程状态,指明进程的当前状态,作为进程调度和对换时的依据
进程优先级,用于描述进程使用处理机的优先级别的一个整数,优先级高的进程应优先获得处理机
进程调度所需的其它信息,它们与所采用的进程调度算法有关,比如,进程已等待CPU的时间总和、进程已执行的时间总和等
事件,指进程由执行状态转变为阻塞状态所等待发生的事件,即阻塞原因。
进程控制信息:
程序和数据的地址,指进程的程序和数据所在的内存或外存地(首)址,以便再调度到该进程执行时,能从PCB中找到其程序和数据
进程同步和通信机制,指实现进程同步和进程通信时必需的机制,如消息队列指针、信号量等,它们可能全部或部分地放在PCB 中
资源清单,即一张列出了除CPU 以外的、进程所需的全部资源及已经分配到该进程的资源的清单
链接指针,它给出了本进程(PCB)所在队列中的下一个进程的PCB的首地址。
PCB的组织方式在一个系统中,通常可拥有数十个、数百个乃至数千个PCB。为了能对它们加以有效的管理,应该用适当的方式将这些PCB组织起来。目前常用的组织方式有以下两种。
线性方式:将系统种所有PCB都组织在一张线性表中,将该表首地址存在内存的一个专用区域
实现简单,开销小,但是每次都需要扫描整张表,适合进程数目不多的系统
链接方式:把同一状态的PCB链接成一个队列,形成就绪队列、若干个阻塞队列和空白队列等
对其中的就绪队列常按进程优先级的高低排列,优先级高排在队前,此外,也可根据阻塞原因的不同而把处于阻塞状态的进程的PCB排成等待I/O 操作完成的队列和等待分配内存的队列等
索引方式:系统根据所有进程的状态建立几张索引表,例如就绪索引表、阻塞索引表等,并把各索引表在内存的首地址记录在内存的一些专用单元中,在每个索引表的表目中,记录具有相应状态的某个PCB在PCB址
进程的控制
进程控制是进程管理最基本的功能,主要包括创建新进程,终止已完成的进程,将发生异常的进程置于阻塞状态,进程运行中的状态转换等
进程创建参数:进程标识、优先级、进程起始地址、CPU初始状态、资源需求等等
创建进程的过程:
创建一个空白PCB
为新进程分配所需资源
初始化PCB
标识信息,将系统分配的标识符和父进程标识符填入新PCB
处理机状态信息,使程序计数器指向程序入口地址,使栈指针指向栈顶
处理机控制信息,将进程设为就绪/静止状态,通常设为最低优先级
如果就绪队列能接纳,则插入
进程终止进程终止的时机/时间:
正常结束
异常结束
越界错,访问的存储区越出该进程的区域
保护错,试图访问不允许访问的资源,或以不适当的方式访问(写只读)
非法指令,试图执行不存在的指令(可能是程序错误地转移到数据区,数据当成了指令)
特权指令出错,用户进程试图执行一条只允许OS执行的指令
运行超时,执行时间超过指定的最大值
等待超时,进程等待某件事超过指定的最大值
算数运算错,试图执行被禁止的运算(被0除)
I/O故障
外界干预
操作员或OS干预(死锁)
父进程请求,子进程完成父进程指定的任务时
父进程终止,所有子进程都应该结束
终止过程:
根据被终止进程的标识符,从PCB集合中检索出该PCB,读取进程状态
若处于执行状态:立即终止执行,置调度标志为true,指示该进程被终止后重新调度
若进程有子孙进程:将其所有子孙进程终止
全部资源还给父进程/OS
PCB从所在队列/链表中移出
进程阻塞阻塞的时机/事件
请求共享资源失败,系统无足够资源分配
等待某种操作完成
新数据尚未到达(相互合作的进程)
等待新任务
阻塞过程:进程通过block
进程唤醒原语wakeup,和阻塞成对使用
唤醒过程:先把被阻塞的进程从该事件阻塞队列移出,将其PSB状态改为就绪,再插入就绪队列
进程同步 制约关系资源共享关系(间接制约
需要互斥的访问临界资源
相互合作关系(直接制约
临界资源:一次只允许一个进程访问的资源
引起不可再现性是因为临界资源没有互斥的访问
临界区 while(1){ entry; //进入区 critical; //临界区 exit; //退出区 }各进程应互斥进入相关临界区,所谓临界区是指一段代码,一段程序
同步机制应该遵循:
空闲让进
忙则等待
有限等待
让权等待:不能进入临界区的执行进程放弃cpu执行权
整形信号量信号量机制是一种进程间的低级通信方式
s是一个整形量,除了初始化外,仅通过两个原子操作wait(s)和signal(s)访问(也叫P,V操作)
wait(s){ while(s<=0); s--; } signal(s){ s++; }