操作系统-进程
操作系统-进程
操作系统
概念:
为了使参与并发的每个程序(含数据)都独立地运行,在操作系统中必须配置一个专门的数据结构,这个数据结构称为进程控制块(PCB),由程序段,相关的数据段以及PCB构成进程实体,简称进程
进程的特征:
- 动态性
- 并发性
- 独立性
- 异步性
进程的基本状态以及转换
PCB中包含的信息
- 进程标识符
- 外部标识符
方便用户对进程的访问; - 内部标识符
方便系统对进程的访问;
- 外部标识符
- 处理机的状态
处理机的状态信息也叫做处理机的上下文,主要由各种寄存器组成:通用寄存器,指令计数器,程序状态字PSW,用户栈指针。当进程进行切换的时候,上下文信息对被保存在相应的PCB中,以便恢复现场信息 - 进程调度信息
- 程序状态
- 进程优秀级
- 进程调度算法
- 事件
- 进程控制信息
- 程序和数据的地址
进程中程序和数据的内存或者外存地址 - 进程同步和通信机制
实现进程同步和进程通信必须的机制,例如消息队列指针,信息量等 - 资源清单
列出进程在运行期间需要的全部资源 - 链接指针
给出本PCB所在队列中的下一个进程PCB的首地址
- 程序和数据的地址
进程的控制
- 进程创建
一般引起创建进程的事件:
- 用户登录
用户在登录成功的时候,系统会为该用户创建一个进程 - 作业调度
在多道批处理程序中,当作业调度按照一定算法被调度时,将作业装入内存,为其创建进程,加入就绪队列中 - 提供服务
当运行中的用户进程提出请求,系统将创建一个进程来提供用户所需要的服务 - 应用请求
上述三种都是系统内核为用户创建的新进成,这一类是用户自己创建的
- 用户登录
创建过程:
申请空白的PCB--->为新进程分配所需要的资源,包括各种物理和逻辑资源,例如内存,文件,I/O设备,CPU时间等--->初始化PCB--->将PCB插入就绪对列中
-
进程终止
引起进程终止的事件:- 正常结束
当进程任务完成,准备退出运行会有一个用于表示运行完成的指示 -
异常结束
进程在运行的时候发生了某种异常事件,使程序无法继续运行。常见的有:- 越界错
程序访问的存储区已越出了程序的区域 - 保护错
进程试图去访问一个不允许访问的资源或文件,或者以不恰当的方式进行访问 - 非法指令
程序试图去执行一条不存在的指令 - 特权指令错
用户进程试图去执行一条只允许OS执行的指令 - 运行超时
进程的执行时间超过了指定的最大值 - 等待超时
程序等待某事件的事件超过了规定的最大值 - 算术错
进程试图去执行一个被禁止的运算
- 越界错
-
外界干预
进程应外界的请求而终止运行,干预有:- 操作员或操作系统干预
- 父进程请求
- 父进程终止
- 正常结束
进程终止过程:
根据标识符从PCB集合中检索该进程的PCB,读取进程状态--->若进程处于执行状态,终止进程,并置调度标志为真,用于指示进程被终止后应重新进行调度--->终止其子孙进程--->终止进程归还其拥有的全部资源--->将PCB从所在集合中移除,等待其他程序来收集信息
进程阻塞和唤醒
引起阻塞和唤醒的事件:
- 向系统请求共享资源失败
当进程向系统请求资源的时候,系统没有足够的资源分配,进程因此不能继续运行而转变为阻塞状态 - 等待某种操作的完成
当进程启动某种操作后,如果进程必须在该操作之后才能继续执行,则应先将该进程阻塞起来。 - 新数据尚未到达
如果一个进程需要获得另一个进程的数据后才能进行,只要数据没有到达,那么进程就会阻塞 - 等待新任务的到达
在某些系统中会设置一些特定的系统进程,这些进程完成任务后就会把自己阻塞起来,等待新任务
阻塞过程:
进程立即停止执行,将PCB中的现行状态改为阻塞--->PCB插入对应事件的阻塞队列中--->转调度程序重新调度,将处理机分配给另一个就绪进程,并进行切换
唤醒过程
将被阻塞进程PCB从阻塞队列中移除--->将PCB现行状态改为就绪--->将PCB插入到就绪队列中
进程的挂起与激活
- 进程挂起
检查被挂起进程的状态,若处于活动就绪状态,则改为静止就绪,若为活动阻塞状态,则改为静止阻塞,若被挂起进程正在执行,则转向调度程序重新调度 - 进程激活
激活首先将进程从外存调入内存中,然后检查其进程的现行状态,若为静止就绪,则改为活动就绪,若为静止阻塞,则改为活动阻塞,若是在抢占式调度策略的话,需要与当前进程比较优秀级,如果比当前进程优秀级高,则抢占处理机。
进程同步
概念:
进程同步是对多个相关进程在执行次序上进行协调,使并发执行的多个进程之间能够按照一定的规则或者时序共享系统资源。
临界区
每个进程中访问的临界资源的那一段代码
规则:
- 空闲让进
- 忙则等待
- 有限等待
- 让权等待
信号量机制
信号量机制是一种有效解决进程同步问题的工具
- 整型信号量
整型信号量定义一个用于表示资源数目的整型量S,除了初始化外,只能通过wait(S)和signal(S)这两个原子操作访问,这个方法简单但是却不能做到让权等待
wait(S){
while(S<=0);
S--;
}
signal(S){
S++;
}
- 记录型信号量
记录型信号量在整型信号量的基础上加一个进程链表指针,用于链接上述所有的等待进程 - AND型信号量
上述两种都是针对一个临界资源的情况,而要想临界资源则需要有到AND信号量
基本思想:将进程在整个运行过程中需要的所有资源,一次性全部分配给进程,等进程结束之后再一起
-
信号量集
上面三个都仅能对信号量进行加1或者减1操作,意味着每次只能对一个临界资源申请或释放,如果需要N个的话,需要进行N次,效率有能低,甚至会增加死锁的概率。信号量集是对AND信号量机制加以扩充,对进程锁申请的所有资源以及每类资源不同的资源需求量。如果进程对信号量S不再是1,而是分配下限值t,若S < t,则不分配,一旦允许分配,进程对资源的需求值为d,即表示资源占用量,格式(S,t,d)
信号量集的特殊情况:
- Swait(S,d,d)
此时只有一个信号量S,但允许它每次申请d个资源,当现有资源少于d,不予分配 - Swait(S,1,1)
一个表示一般的记录型信号量(S>1)或互斥信号量(S=1) - Swait(S,1,0)
一种特殊且很有用的信号量操作。当S>=1是,允许多个进程进入某特定区,当S为0的时候,阻止任何进程进入。相当于一个可控的开关