1. 进程的同步:直接作用
进程同步是指系统中多个进程发生的时间存在某种时序关系,需要相互合作,共同完成一项任务。
司机售票员问题:
司机P1 售票员P2
while(true) while(true)
{ {
P(run);
启动车辆; 关门;
V(run);
正常运行; 售票;
P(open);
到站停车; 开门;
V(open);
} }
P、V问题的初步思考:考虑事件A的先决条件时间B,在事件B后V,然后再事件A前P。
2. 进程的互斥:间接作用
系统中的某些资源一次只允许一个进程使用,称这样的资源为临界资源或互斥资源或共享变量。
3. 临界区
临界区:在进程中涉及临界资源的程序段叫临界区。
使用临界区遵循以下原则:
- 有空让进
- 无空等待
- 多中择一
- 有限等待
- 让权等待
4. P操作
P(s)
{
s.value -- ;
if (s.value < 0)
{
该进程状态置为等待状态;
该进程的PCB插入相应的等待队列s.queue的末尾;
}
}
5. V操作
V(s)
{
s.value ++ ;
if (s.value <= 0)
{
唤醒相应等待队列s.queue中等待的一个进程;
改变器状态为就绪态,并将其插入就绪队列;
}
}
6. 生产者消费者问题
生产者:
while(true)
{
生产一个产品;
P(s1);
送产品到缓冲区;
V(s2);
}
消费者:
while(true)
{
P(s2);
从缓冲区取产品;
V(s1);
消费产品;
}
7. P、V操作的讨论
- P、V操作必须成对出现。
- 当为互斥操作时,它们处于同一进程。
- 当为同步操作时,则不在同一进程中出现。
- 同步P操作在互斥P操作之前,两个V操作无关紧要。
8. 哲学家吃通心面问题
Var fork[I]:array[0..4] of semaphore;
fork[i] := 1;
cobegin
process Pi //i=0,1,2,3,4
begin
L1:
思考;
P(fork[i]); //先拿左边叉子
P(fork[(i+1)mod5]; //再拿右边叉子
吃通心面;
V(fork[i]); //归还左边叉子
V(fork[(i+1)mod5]; //归还右边叉子
goto L1;
end;
coend
9. 生产者消费者问题升级版
var B : array[0..k-1] of item;
empty : semaphore := k; //缓冲区数
full : semaphore := 0; //缓冲区可以使用的产品数
mutex : semaphore := 1;
in, out : integer := 0; //放入和取出缓冲区指针
cobegin
process producer_i
begin
L1: produce a product;
P(empty);
P(mutex);
B[in] := product;
in := (in+1) mod k;
V(mutex);
V(full);
goto L1;
end;
process consumer_j
begin
L2:P(full);
P(mutex);
product := B[out];
out := (out+1) mod k;
V(mutex);
V(empty);
consume a product;
goto L2;
end;
coend
10. 读者写者问题
var rc : integer := 0; //读进程数
W, R : semaphore := 1
cobegin
procedure read;
begin
P(R);
rc := rc + 1;
if rc=1 then P(W);
V(R);
读文件;
P(R);
rc := rc - 1;
if rc = 0 then V(W);
V(R);
end;
procedure write;
begin
P(W);
写文件;
V(W);
end;
coend
11. 死锁的基本概念
死锁被定义为系统中两个或者多个进程无限期地等待永远不会发生的条件,系统处于停滞状态。
12. 产生死锁的原因
- 因为系统资源不足;
- 系统运行推进的顺序不合适;
- 资源分配不当。
13. 产生死锁的4个必要条件
- 互斥使用:一个资源每次只给一个进程使用;
- 不可强占(不可剥夺):资源申请者不能强行从资源占有者手中夺取资源;
- 请求和保持:一个进程在申请新的资源的时候还占有原有的资源;
- 循环等待:形成进程等待环路。
14. 死锁的解决方法
死锁的预防
- 破坏“不可剥夺”条件:成为为等待状态之前,释放已占有的全部资源;
- 破坏“请求和保持”条件:一次性分配;
- 破坏“循环等待”条件:将系统中的资源编号,申请资源必须严格按编号递增次序进行。
死锁的避免——银行家算法
对进程的申请进行试分配,分配后系统状态为安全状态则予以分配,否则不行。
安全状态:如果系统中的所有进程能够排成一个安全序列,则系统处于安全状态。
死锁的检测及解除
检测手段:利用进程-资源分配图
- 方框表示资源类
- 方框中的黑圆点表示资源实例
- 圆圈加进程名表示进程
- 资源实例指向进程的有向边表示分配边
- 进制指向资源类的有向边表示申请边
检测步骤:
- 在图中找一个找一个只有分配边的非孤立进程结点,去掉分配边,将其变为孤立结点,去掉分配边,将其变为孤立结点;若找不到择转3;
- 将相应的资源分配给一个等待该资源的进程,即将某进程的申请边变为分配边,转1;
- 此时若图中有进程不是孤立结点,则此图不可完全简化,满足死锁的充分条件。
死锁的解除:
资源剥夺法:当发现死锁后,从其他进程那里剥夺足够数量的资源给死锁进程,以解除死锁状态。
撤销进程法:撤销全部死锁进程,使系统恢复到正常状态,最简单但代价大;按照某种顺序逐个撤销死锁进程,资源给未撤销的进程用,直到消除死锁为止。