第2章 进程管理
2.1 进程与线程
-
进程
- 程序的一次执行过程
1
. 进程的概念
系统进行资源分配和调度的基本单位
2
. 进程的特征
- 动态性:最基本的特征
- 并发性
- 独立性
- 异步性
- 结构特征:程序段、数据段和PCB
- 内存空间开销
- 内存时间开销
2.1.2 进程的状态与转换
1
. 三状态模型
- 运行状态
- 阻塞状态
- 就绪状态
2
. 五状态模型
- 新建状态
- 终止状态
3
. 就绪挂起状态和阻塞挂起状态
2.1.3 进程控制
1
. 进程控制机构
原语
2
. 主要进程原语
- 创建原语
- 撤销原语
- 阻塞原语
- 唤醒原语
- 挂起原语
- 激活原语
2.1.4 进程组织
1
. 进程实体
- 程序
- 数据集合
PCB
2
. 进程控制块(PCB
)
2.1.5 进程通信
- 共享内存
- 消息传递
- 管道机制
2.1.6 线程概念与多线程模型
1
. 线程的发明
2
. 线程的实现方式
- 内核线程:与进程一起获得相同的时间配额
- 用户线程:一旦阻塞,整个进程阻塞
3
. 进程机制与线程机制的比较
4
. 多线程模型
2.2 处理机调度
2.2.1 调度的基本概念
1
. 作业调度
2
. 进程调度
3
. 交换调度
2.2.2 调度的时机、切换和过程
1
. 引起调度的事件
2
. 调度队列
3
. 分派程序
2.2.3 调度的基本原则
- 处理机利用率
- 吞吐量
- 周转时间:从提交到完成用的时间
- 后备时间:从外存到内存的时间
- 等待时间:就绪队列中等待处理机调度的时间
- 响应时间:出结果
2.2.4 调度方式
- 不可抢先方式不讨论,很无聊!
- 可抢先方式
进程调度算法比较
先来先服务算法【FCFS】
- 短作业或短进程优先【SJF&SPF】
- 高响应比优先调度算法【HRRN】
- 高优先级优先调度算法
- 时间片轮转算法【RR】
- 多级反馈队列算法
响应比Rp=等待时间+预计运行时间预计运行时间=周转时间预计运行时间
2.3 同步与互斥
2.3.1 进程同步与互斥的基本概念
1
. 基本概念
- 直接相互制约:进程合作:进程同步
- 间接相互制约:资源共享:进程异步
- 临界资源:一次只允许一个进程使用的资源
- 临界区:访问临界区的那段程序
2
. 同步机制应遵循的准则
- 空闲则进
- 遇忙等待
- 有限等待
- 让权等待
2.3.2 实现临界区互斥的基本方法
1
. 算法一:单标志法
// P0 | // P1
while(turn != 0) | while(turn != 1)
; | ;
critical section | critical section
turn = 1; | turn = 0;
remainder section | remainder section
一个公用整型变量 turn,用于指示被允许进入临界区的进程编号。
2
. 算法二:双标志法先检查
// P0 | // P1
while(flag[j]) | while(flag[i])
; | ;
flag[i] = true; | flag[j] = true;
critical section; | critical section;
flag[i] = false; | flag[j] = false;
remainder section; | remainder section;
3
. 算法三:双标志法后检查
// Pi | // Pj
flag[i] = true; | flag[j] = false
while(flag[j]) | while(flag[i])
; | ;
critical section | critical section
flag[i] = false; | flag[j] = true
remainder section | remainder section
4
. Peterson’s Algorithm
// Pi | // Pj
flag[i] = true; | flag[j] = true;
turn = j; | turn = i;
while(flag[j] && turn == j) | while(flag[i] & turn == i)
; | ;
critical section | critical section
flag[i] = false | flag[j] = false
remainder section | remainder section
2.3.3 信号量
1
. 信号量
-
S
- 一个整型变量,初值为非负数 Q
- 一个初始状态为空的等待队列,大于0表示系统中当前可用资源的数量,小于1表示系统中等待使用该资源的进程数目
--S.Q;
if (S.Q < 0)
{
调用进程进入等待队列 S.Q;
阻塞调用进程;
}
++S.Q;
if (S.Q <= 0)
{
从等待队列 S.Q 中取出一个进程 P;
进程 P 进入就绪队列;
}
2
. 实现同步模型
3
. 实现互斥模型
2.3.4 管程
2.3.5 经典的同步和互斥问题
1
. 生产者-消费者问题
semaphore mutex = 1; // 临界区互斥信号量
semaphore empty = N; // 空闲缓冲区
semaphore full = 0; // 缓冲区初始化为空
void producer() | void consumer()
{ | {
while(true) | while(true)
{ | {
item = produce_item(); | P(full);
| P(mutex);
P(empty); |
P(mutex); | item = remove_item();
|
insert_item(); | V(mutex);
| V(empty);
V(mutex); | }
V(full); | }
} |
}
先创造条件再生产
2
. 读者-写者问题
semaphore rmutex = 1;
semaphore wmutex = 1;
int readcount = 0;
void reader() | void writer()
{ | {
P(rmutex); | while(true)
readcount++; | {
if(readcount == 1) | think_up();
P(wmutex); | P(wmutex);
V(rmutex); |
| write_data_base();
read_data_base(); |
| V(wmutex);
P(rmutex); | }
readcount--; | }
if(readcount == 0) |
V(wmutex); |
V(rmutex); |
} |
3
. 哲学家进餐问题
semaphore chopsticks[5] = { 1, 1, 1, 1, 1}; | semaphore chopsticks[5] = { 1, 1, 1, 1, 1};
| semaphore eating = 4;
void philosopher(int i) |
{ | void philosopher(int i)
while(true) | {
{ | while(true)
thinking(); | {
P(chopsticks[i]); | thinking();
P(chopsticks[(i+1)%5]); | P(eating);
| P(chopsticks[i]);
eating(); | P(chopsticks[(i+1)%5]);
|
V(chopsticks[i]); | eating();
V(chopsticks[(i+1)%5]; |
} | V(chopsticks[(i+1)%5]);
} | V(chopsticks[i]);
| V(eating);
| }
| }
|
|
semaphore chopsticks[5] = { 1, 1, 1, 1, 1}; | semaphore chopsticks[5] = { 1, 1, 1, 1, 1};
semaphore mutex = 1; |
| void philosopher(int i)
void philosopher(int i) | {
{ | while(true)
while(true) | {
{ | thinking();
thinking(); |
P(mutex); | if(i%2 == 0)
P(chopsticks[i]); | {
P(chopsticks[(i+1)%5]); | P(chopsticks[(i+1)%5]);
V(mutex); | P(chopsticks[i]);
|
eating(); | eating();
|
V(chopsticks[(i+1)%5]); | V(chopsticks[(i+1)%5]);
V(chopsticks[i]); | V(chopsticks[i]);
} | }
} | else
| {
| P(chopsticks[i]);
| P(chopsticks[(i+1)%5]);
|
| eating();
|
| V(chopsticks[i]);
| V(chopsticks[(i+1)%5]);
| }
| }
| }
2.4 死锁
2.4.1 死锁的概念
1
. 死锁的概念
2
. 死锁产生的原因
- 进程推进顺序不当
- 对互斥资源的分配不当
3
. 产生死锁的四个必要条件
- 互斥条件
- 请求并占用
- 非剥夺条件
- 循环等待
2.4.2 死锁处理策略
- 忽略
- 检测与恢复
- 避免
- 预防
2.4.3 死锁忽略
鸵鸟算法
2.4.4 死锁检测和恢复
1
. 资源分配图
-
死锁定理
- 系统处于死锁状态的充分必要条件是,当且仅当该状态的资源分配图是不可完全简化的.
2
. 资源矩阵
3
. 死锁的解除与系统恢复
2.4.5 死锁避免
1
. 安全状态与不安全状态
2
. 银行家算法
2.4.6 死锁预防
- 破坏互斥条件:
spooling
技术 - 破坏请求并占用条件:一次性申请所有资源
- 破坏非剥夺条件:资源暂时释放策略
- 破坏循环等待条件:资源有序申请