定义
进程的典型定义:进程是程序的一次动态执行
进程在传统OS中的定义: 进程是进程实体的运行过程,是系统进行资源分配和调度的独立单位.
一般情况下,我们所说的进程实体(也叫进程映像)简称进程,进程实体包括程序段,数据段和进程控制块(PCB).
PCB
创建进程的实质就是创建PCB,撤销进程实质也是撤销PCB.
PCB作用:作为独立运行的基本标志, 实现间断性运行方式, 提供进程管理需要的信息,提供进程调度需要的信息, 与其他进程通信
PCB包含的信息
1.进程标识符:外部标识符,内部标识符
2.处理机状态:通用寄存器, 指令计数器, 程序状态字, 用户栈指针
3.进程调度信息:进程状态, 进程优先级, 进程调度的其他信息, 事件
4.进程控制信息:程序和数据地址, 进程同步和通信机制, 资源清单,链接指针
进程控制块的组织方式:线性方式, 链接方式, 索引方式
线性方式:所有的PCB都组织在一张线性表中
链接方式:具有相同状态的PCB通过PCB中的链接字链接成一个队列.
索引方式:系统根据进程状态建立几张索引表.
进程的特征
动态性:有创建而产生,由调度而执行,由撤销而消亡.程序只是一组有序指令的集合
并发性:多个进程实体在内存中,且在一段时间内同时运行.程序没有建立PCB所以不能并发执行,只能顺序执行
独立性:进程是一个能独立运行,独立获得资源和独立就收调度的进本单位.
异步性:进程按各自独立的, 不可预知的速度运行.
进程的状态与转换
三个基本状态:
就绪状态:只要获得cpu就可以立即执行
执行状态:已获得cpu正在执行
阻塞状态:因发生某些事件(I/O请求等)放弃cpu而暂停执行.
引入挂起
原因:终端用户的需要, 父进程请求, 负荷调节, 操作系统的需要
状态转换:
进程控制
引起创建进程的事件:用户登录, 作业调度, 提供服务, 应用请求
创建进程
1.申请空白PCB
2.为新进程分配所需资源
3.初始化进程控制块PCB
4.新进程插入就绪队列
引起进程终止的事件:正常结束, 异常结束(越界错, 保护错, 非法指令, 运行超时等), 外界干预
终止进程
1.找到该进程的PCB
2.终止进程及其子孙进程
3.回收该进程所占资源
4.移出进程所在队列
引起进程阻塞和唤醒的事件:向系统请求共享资源失败, 等待某种操作的完成, 新数据尚未到达, 等待新任务的到达.
阻塞进程
1.停止执行进程(失去cpu)
2.改变进程状态
3.插入阻塞队列
唤醒进程:
1.移除阻塞队列
2.检查并改变进程状态
3.插入就绪队列
挂起进程:
1.改变进程转态
2.赋值进程PCB到指定内存
3.若挂起进程正在执行则重新调度
激活进程:
1.将进程从外存调入内存
2.检查并改变进程状态
进程同步
并发进程在执行次序上的协调,以达到有效的资源共享和相互合作,使程序执行有可再现性
进程间可能存在的制约关系:间接制约(并发进程互斥的访问临界资源), 直接制约(进程需相互合作执行)
临界资源:一次只允许一个进程访问
临界区:进程中访问临界资源的代码称为临界区
进入区:检查临界资源是否正被访问的代码
退出去:检查临界资源是否访问完毕的代码
实现临界区互斥的基本方法
软件方法:信号量,管程(遵循原则:空闲让进, 忙则等待, 有限等待, 让权等待)
硬件方法:关闭中断,硬件指令(TS, Swap)
信号量机制
整型信号量
wait(S){ while(S<=0); S--; } signal(S){ S++; }
记录型信号量
typedef struct{ int value; struct process_control_block *list; }semaphore; wait(semaphore *S){ S->value--; if(S->value<0)block(S->list); } signal(semapohre *S){ S->value++; if(S->value<=0)wakeup(S->list); }
AND型信号量
一次性全部分配
Swait(S1, S2, …, Sn) if Si≥1 and … and Sn≥1 then for i∶ =1 to n do Si∶=Si-1; endfor else place the process in the waiting queue associated with the first Si found with Si<1, and set the program count of this process to the beginning of Swait operation endif Ssignal(S1, S2, …, Sn) for i∶ = 1 to n do Si=Si+1; Remove all the process waiting in the queue associated with Si into the ready queue. endfor;
信号量集
(S:信号量, d:需求值, t:下限值, t>=d)
Swait(S1, t1, d1, …, Sn, tn, dn) if Si≥t1 and … and Sn≥tn then for i∶=1 to n do Si∶=Si-di; endfor else Place the executing process in the waiting queue of the first Si with Si<ti and set its program counter to the beginning of the Swait Operation. endif signal(S1, d1, …, Sn, dn) for i∶=1 to n do Si ∶=Si+di; Remove all the process waiting in the queue associated with Si into the ready queue endfor;
经典的进程同步问题
由进程同步而引起的一些经典的进程同步问题(生产者消费者问题, 哲学家进餐问题, 读写问题)可以在我的另一篇文章中查看.
管程
管程 (英语:Monitors,也称为监视器) 是一种程序结构,结构内的多个子程序(对象或模块)形成的多个工作线程互斥访问共享资源。这些共享资源一般是硬件设备或一群变量.
代表共享资源的数据结构以及由对该共享数据结构实施操作的一组过程所组成的资源管理程序共同构成了一个操作系统的资源管理模块,我们称之为管程.
由定义, 管程由四部分组成:
1.管程的名称;
2.局部于管程内部的共享数据结构说明;
3.对该数据结构进行操作的一组过程;
4.对局部于管程内部的共享数据设置初始值的语句
(维基百科)一个管程包含:
多个彼此可以交互并共用资源的线程
多个与资源使用有关的变量
一个互斥锁
一个用来避免竞态条件的不变量
管程特性:
1.模块化, 管程是一个基本程序单位,可以单独编译
2.抽象数据类型, 管程中不仅有数据, 还有对数据的操作
3.信息掩蔽, 管程中的数据结构只能被管程的过程访问, 这些过程也是在管程内部定义的, 共管程外的进程调用, 而管程中的数据结构及过程(函数)的具体实现外部不可见.
管程与进程的对比:
1.管程定义的是公共数据结构, 进程定义的是私有数据结构PCB
2.管程对数据结构进行同步和初始化, 进程则对数据结构进行顺序程序执行
3.管程用于解决共享资源互斥, 进程用于实现系统的并发性
4.管程是被动工作, 进程是主动工作
条件变量
管程的条件变量:条件变量是在管程内部的数据结构,且只有在管程内才能被访问,它对管程内所有过程是全局的,只能通过x.wait(),x.signal()两个操作访问.
x.wait():正在调用的管程因x条件需要被阻塞或挂起, 则调用x.wait()将自己插入到x条件的等待队列上, 并释放管程, 知道x条件变化.
xsignal():正在调用管程的进程发现x发生了变化, 则调用x.siganl(), 重新启动一个因x条件而阻塞或挂起的进程, 如果存在多个这样的进程, 则选择其中的一个, 如果没有则继续执行原进程, 而不产生任何结果.
线程-调度和分派的基本单位
由来:
自古以来熊和鱼掌不可兼得, 同样对于进程来讲, 作为调度和分派的基本单位同时又拥有资源这会加重系统开销. 那么能否将它们分开呢? 对于拥有资源的单位, 并不频繁的进行上下文切换, 于是线程便诞生了.进程作为拥有资源的单位, 线程作为独立调度和分派的单位. 一个进程可拥有多个线程. 在多线程中, 可将每个线程称为一个任务. 宏观上, 进程也是任务.
线程, 有时被称为轻量级进程(Lightweight Process, LWP), 是程序执行流的最小单元.相对的, 传统的进程叫做重型进程.
线程与进程的比较
调度的基本单位:传统OS中, 进程是独立调度和分派的基本单位, 占有资源独立运行, 但是在引入线程的OS中, 线程是调度的基本单位, 可以独立运行的, 此时进程已不是可以独立运行的实体.
并发性:一个进程中拥有多个线程, 称为多线程. 这多个线程可以并发运行.不同进程间的线程也可并发运行.
拥有资源:进程是系统中拥有资源的基本单位, 而线程只有一点必不可少的, 能保证独立运行的资源, 这大大减少了系统的开销.
独立性:每个进程拥有一个独立的地址空间和资源, 除了共享全局变量以外不允许其他进程访问.同一进程中的线程除了只拥有自身必须的少量资源, 它们共享进程的内存地址空间和资源
系统开销:进程因为拥有资源, 每次调度进程时必定要对其分配回收, 系统开销大.线程只占有极少的资源, 其系统开销远低于进程.
线程的三个基本转态
就绪状态: 只要活得cpu就可执行
执行状态: 活得cpu正在执行
阻塞状体: 线程因某种原因受阻而暂停执行
线程控制块TCB
系统为每个进程配置了一个进程控制块PCB用于管理进程.同样, 也有一个线程控制块TCP用户控制和管理线程.它包括:
1.线程标识符: 线程ID
2.寄存器:程序计数器, 状态寄存器, 通用寄存器
3.线程运行状态
4.优先级: 线程的优先级
5.线程专有存储区
6.信号屏蔽
7.堆栈指针