第2章-2 进程同步

本文详细介绍了进程同步的概念,包括临界资源、临界区、同步机制的准则和实现方法,如信号量机制。重点讲解了生产者-消费者问题、哲学家进餐问题和读者-写者问题,阐述了如何利用信号量解决这些问题,确保并发执行的正确性和效率。
摘要由CSDN通过智能技术生成

2.4 进程同步

2.4.1 进程同步的基本概念

程序顺序执行:顺序性,封闭性,可再现性
程序并发执行:间断性,失去封闭性,不可再现性
进程异步性:各并发执行的进程以各自独立的、不可预知的速度向前推进。

进程同步机制的任务:
对多个相关进程在执行次序上进行协调,使并发执行的进程能按照一定的规则(次序)共享系统资源,并能很好地相互合作,从而使程序的执行具有可再现性。

在这里插入图片描述
例:生产者—消费者问题进程P1和进程P2共享一个缓冲区,假设:进程P1写数据,进程P2读数据,他们需要一定的同步机制。

P1进程:
是否有空缓冲区
有,写入,唤醒P2
没有:阻塞自己
P2进程:
缓冲区是否有数据
有,读出,唤醒P1
没有:阻塞自己
在这里插入图片描述
两个进程的读写有一定的顺序:有空缓冲区且可写入,有数据且可读操作。
问题:如何判断缓冲区是否有数据? 设置变量S=0(空)

例:进程P1和P2共享一个公用变量S,假设P1对变量S进行加1操作,而P2对变量S进行减1操作。
在这里插入图片描述

假设s的当前值是1,
(1)先执行语句 ①、②、③,再执行语句 ④、⑤、⑥,则S=1;
(2)先执行语句 ④、⑤、⑥,再执行语句 ①、②、③,则S=1;
(3)执行语句的次序为 ①、②、④、⑤、③、⑥,则S=0;

对共享数据的并发操作可能导致结果不同,why?
解决办法:把公用变量S作为临界资源,进程P1和P2互斥访问变量S。
进入前判断是否有进程处于临界区。

2.4.1.1 临界资源与临界区(critical section)

临界资源:某段时间内只能允许一个进程使用的资源;如:打印机、磁带机、某个文件、共享变量

临界区: 进程中访问临界资源的代码段

多个进程互斥地访问,一个进程在临界区内,其他等待。

访问临界区的循环进程描述:

在这里插入图片描述

2.4.1.2 同步机制应遵循的准则

  1. 空闲让进。无进程处于临界区时,表明临界资源处于空闲状态,若有进程要求进入临界区,应立即允许进入。
  2. 忙则等待。当已有进程进入其临界区时,该临界资源正在使用,所有其他欲访问该临界资源的进程必须等待,以保证各进程互斥地进入其临界区。
  3. 有限等待。对要求访问临界资源的进程,应在有限时间内使一个进程进入临界区,不应出现各进程相互等待都无法进入临界区的情况,避免“死等”。
  4. 让权等待。当进程不能进入其临界区时,应立即释放所占有的CPU,以免陷入“忙等待”,保证其他可执行的进程获得CPU运行。

2.4.1.3 实现进程同步的两类方法

  1. 硬件指令方法:通过计算机提供的一些机器指令实现 进程
    进程的互斥。
    在这里插入图片描述

  2. 信号量机制:为并发进程设置标志,表示进程是否在临界区,例如信号量

2.4.2 硬件同步机制

  1. 开关中断指令
  1. 进程在进入临界区之前先执行“关中断”指令,屏蔽掉所有中断;
    进程完成临界区的任务后,再执行“开中断”指令打开中断。
  2. 关中断后,计算机不响应中断,不引发调度,不会进程切换。
process Pi() // i=1, 2, 3, …, n { … //与临界资源无关的代码
lock out interrupts; //关中断
临界区;
unlock interrupts; //开中断//与临界资源无关的剩余代码
}

优点:简单、高效;
缺点:滥用关中断权利可能导致严重后果;关中断时间过长,影响系统效率;适用于OS内核进程,不适用于用户进程;

  1. 测试与设置指令TS(Test and Set)
  1. TS指令用硬件实现,执行的过程不会被中断,执行过程不被分割;
    为每个临界资源设置一个布尔变量lock,可以将它看成一把锁。
  2. Lock=FALSE,表示空闲,开锁;
  3. Lock=TRUE, 正在被用,关锁
  4. 利用TS指令实现进程互斥的程序结构
    在这里插入图片描述
    在这里插入图片描述

2.4.3 信号量机制(semaphore)

  1. 信号量是一种特殊的变量,只能进行两种操作:P、V操作;
  2. 多个进程通过信号量进行交互,广泛应用的同步方法。
    在这里插入图片描述
    类型:整型信号量、记录型信号量、AND信号量,信号量集

2.4.3.1 整型信号量

  1. 信号量是一种特殊的变量,表现形式为一个整型变量;
  2. 信号量表示系统中某种资源的数量;
  3. 例:系统中有一台打印机,则: int S=1;
  4. 操作:P操作,wait(S), 申请一个资源;
    V操作,signal(S),释放一个资源
    在这里插入图片描述

2.4.3.2 记录型信号量

分量1是整型变量,当前相应资源的可用数量;
分量2是队列指针,指向因等待同类资源而阻塞的进程队列。
结构体型信号量可描述如下:

typedef struct
{ int value; //初值表示系统中某类资源的数量
 struct PCB *L; //struct PCB为PCB对应的结构体类型
 //L为指向阻塞队列的指针
 } semaphore;
 semaphore S;

S.value的值:
(1)当S.value>0时,表示该类资源的可用数量。
(2)当S.value=0时,表示该类资源为空。
(3)当S.value<0时,表示因等待该类资源而阻塞的进程数量。
若S.value的初值为1 : 表示只有一个临界资源,一段时间内只允许一个进程访问该资源。
在这里插入图片描述

2.4.3.3 AND 型信号量

AND 型信号量同步机制思想:对于进程在整个运行过程中需要的所有资源,要么一次性地全部分配给该进程,要么一个也不分。
数据结构:类似记录型信号量的数据结构。
在这里插入图片描述
在这里插入图片描述

2.4.4 信号量的应用

  1. 使用信号量实现程序或语句之间的前趋关系
    S1-S6是程序段,他们可以并发执行,他们之间的前趋关系图如下,写出一个可并发执行的程序。
    在这里插入图片描述
P1( ) { S1; V(a); V(b);} 
P2( ) { P(a); S2 ; V(c); V(d); } 
P3( ) { P(b); S3 ; V(e); } 
P4( ) { P(c); S4 ; V(f);} 
P5( ) { P(d); S5 ; V(g); } 
P6( ) { P(e); P(f); P(g); S6 ;}
main() {
semaphore a, b, c, d, e, f, g;
a.value=0; …
cobegin
p1(); p2(); p3(); p4(); p5();p6();
coend
  1. 使用信号量实现进程互斥
    为临界资源设置一个互斥信号量mutex,初值为1;
    将各进程的临界区置于P(mutex) 和V(mutex)之间。
semaphore mutex; //程序模型
mutex.value=1;
process Pi( ) // i=1, 2, 3, …, n
{//与临界资源无关的代码
P(mutex);
临界区;
V(mutex);//与临界资源无关的剩余代码
}
  1. 分析临界区
  2. 设置互斥信号量
  3. 在临界区之前执行p
  4. 在临界区之后执行v

注意: P操作和V操作必须成对出现
缺P操作会导致系统混乱,不能保证对临界资源的互斥访问。
缺V操作将会使该临界资源永久不被释放。

2.5 经典进程同步问题

进程同步:要让各并发进程按要求有序地推进,保证某些操作“一前一后”执行

2.5.1 生产者—消费者问题

  1. 有限缓冲区问题;
  2. 生产者是指提供某一产品(数据)的进程;
  3. 消费者是指使用某一个产品(数据)的进程
  4. 例:生产者与消费者共享一个缓冲池,生产者向其中投放产品,消
    费者从中取出产品消费,缓冲区互斥地使用。
    在这里插入图片描述

问题描述:

  1. 若干进程通过有限的共享缓冲区交换数据。其中,"生产者"进程不断写入,而"消费者"进程不断读出;共享缓冲区共有N个;任何时刻只能有一个进程可对共享缓冲区进行操作。
  2. 分析信号量的设置:
    mutex:对缓冲池的互斥使用,初值为1。
    empty:表示缓冲池中空缓冲区的数量,初值为N。
    full: 表示缓冲池中满缓冲区的数量,初值为0

生产者-消费者程序:
在这里插入图片描述

int in=0,out=0;
item buffer[n];
Semaphore mutex=1, empty=n, full=0;
void proceducer( )
do {
producer an item nextp;//生产产品
wait(empty);
wait(mutex);
buffer(in)=nextp; //放入缓冲区
in=(in+1) % n;
signal(mutex);
signal(full);
} while(TRUE)
}
void consumer( )
do {
wait(full);
wait(mutex);
nextc =buffer(out);//取出产品
out =(out+1) % n;
signal(mutex);
signal(empty);
//消费产品
consumer the item in nextc;} while(TRUE) 
void main()
cobegin
proceducer( ); consumer( );
coend

2.5.2 哲学家进餐问题

问题描述:

5个哲学家同坐在一张圆桌旁,每个人的面前摆放着一个盘子,盘子两旁各摆放着一只筷子。
假设哲学家除了吃饭就是思考问题。吃饭时,需要拿到左右两只筷子,才能进餐。吃完后放下筷子,继续思考。

分析应用场景。各拿1只筷子,陷入死锁。

关系分析:5个哲学家与左右邻居对中间筷子的访问是互斥关系。临界资源:筷子。Semaphore chopstick[5],初值1;
整理思路:有5个进程,关键是如何让一个哲学家拿到左右筷子,而不造成死锁或者饥饿现象
解决方法:对每个哲学家的动作制定规则,让某位哲学家拿到两只筷子。

方法1:最多允许4位哲学家同时拿起左手的筷子:
保证至少有一个哲学家能够进餐,总会释放出他使用过的两支筷子,从而使其他哲学家进餐。

semaphore mutex, chopstick[5];
mutex.value=4;
for (i=0;i<5;i++) chopstick[i].value=1;
process Philosopher_i( ) // i=0, 1, 2, 3, 4
{ while(1)
{ think(); //思考
P(mutex); //最多允许4个哲学家申请筷子
P(chopstick[i]); //拿起左手的筷子
P(chopstick[(i+1)%5]); //拿起右手的筷子
eat(); //进餐
V(chopstick[i]); //放回左手的筷子
V(chopstick[(i+1)%5]); //放回右手的筷子
V(mutex); //已拿到两个筷子,解除申请
} }

方法2:同时拿起两只筷子:
仅当哲学家的左右两支筷子均可用时,才允许他同时拿起左、右手的两支筷子,否则一支筷子也不拿。
利用AND型信号量机制实现,进程需要多个临界资源,要么全部分配给它,要么一个都不分配,因此不会出现死锁的情形。

semaphore chopstick[5];
for(int i=0;i<5;i++)
chopstick[i].value=1;
process Philosopher_i() // i=0, 1, 2, 3, 4
{
while(1)
{
think(); //思考
SP(chopstick[i],chopstick[(i+1)%5]); //同时拿起左右两只筷子
eat(); //进餐
SV(chopstick[i],chopstick[(i+1)%5]); //同时放回两只筷子
} }

2.5.3 读者-写者问题

问题描述:

计算机系统中的数据(文件、记录)常被多个进程共享,但某些进程可能只要求读数据,另一些进程则要求修改数据。
Reader和Writer是两组并发进程,共享一组数据区,要求:
(1)允许多个读者同时执行读操作;
(2)不允许读者、写者同时操作;

信号量设置
reader和writer进程间读或写的互斥 wmutex,初值为1;
整型变量readcount,表示正在读的进程数量,初值为0;
readcount 被多个进程互斥访问,是临界资源,设置信息量rmutex;

利用记录型信号量:

int readcount=0; //记录当前的读者数量
semaphore rmutex=1; //对共享变量readcount 操作的互斥信号量
semaphore wmutex=1; //保证读者和写者互斥地访问
void reader()
do{
P(rmutex); //判断是否有读者,是否首个读者
if (readcount==0) //如是首个读进程,判断是否有写进程在临界区
P(wmutex); //若有,读进程等待;若无,阻塞写进程
readcount ++; //读进程数加1
V(rmutex); //结束对rc的互斥访问
读文件;
P(rmutex); //开始对rc的互斥访问
readcount--; //一个读进程读完,读进程数减1
if (readcount == 0) //最后的读进程需要设置
V(wmutex)//若有,唤醒一个写进程进临界区
V(rmutex); //结束对rc的互斥访问
} while(1)
void writer()
do{
P(wmutex); //无进程访问,进入写进程;
写文件; 
V(wmutex); //写进程完成
} while(1)

总结:进程同步

临界资源:某段时间内只能允许一个进程使用的资源;如:打印机、磁带机、某个文件、共享变量;
临界区: 进程中访问临界资源的代码段
互斥访问:多个进程互斥地访问,一个进程在临界区内,其他等待。

访问临界区的循环进程描述:
在这里插入图片描述

总结:PV操作讨论

PV操作必须成对出现,有一个P操作,就一定有一个V操作;
在这里插入图片描述
对于前后相连的两个P(S1)和P(S2) ,顺序是至关重要的同步P操作应该放在互斥P操作前。

例题及参考答案

  1. 下面的活动中,每个活动属于同步与互斥关系的哪一种,并说明其理由。(间接制约关系、直接制约关系)
    (1)若干同学去图书馆借书;
    (2)两队举行篮球比赛;
    (3)流水线生产的各道工序;
    (4)商品生产和社会消费。

解:
1)是间接相互制约:由于借相同的书(资源)而产生相互制约;
2)是间接相互制约:由于占用相同的场地(资源)而产生相互制约;
3)是直接相互制约:在流水线生产中,只有完成上一个流程,下一步才可以继续;
4)是直接制约,两者也需要相互合作:商品生产出来后才可以被消费;商品被消费后才需要再生产。

  1. 若一个系统中共有5个进程涉及某个相同的变量A,则变量A的
    相关临界区是由(C)个临界区构成的。
    A 1
    B 3
    C 5
    D6

  2. 有一个计数信号量S:
    1)假如若干进程对S进行28次P操作和18次V操作后,信号量S值为0 2)假如若干进程对信号量进行了15次P操作和2次V操作,请问此时有
    多少进程等待在信号量S的队列中。(B)
    A 2
    B 3
    C 5
    D 7

  3. 四个进程A、B、C、D都要读一个共享文件F,系统允许多个进程同时读文件F。但限制进程A和进程C不能同时读文件F,进程B和进程D也不能同时读文件F。为了使这四个进程并发执行时能按系统要求使用文件,现用P、V操作进行管理,请回答下面的问题:
    ⑴ 如何定义信号量及初值;

答:两个信号量AC和BD,初值为1
在这里插入图片描述
答:[1]: P[AC]
[2]:V[AC]
[3]P[BD]
[4]V[BD]
[5]P[AC]
[6]V[AC]
[7]P[BD]
[8]V[BD]

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值