进程同步-互斥

一、进程同步

在这里插入图片描述
在这里插入图片描述
进程同步为了解决异步问题。进程同步反映进程之间的直接制约关系。

二、今程互斥

在这里插入图片描述

对临界资源的访问进行上锁。
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
进程互斥反映进程的间接制约关系。

三、进程互斥的实现方法

3.1 软件实现方法

在这里插入图片描述
在这里插入图片描述

1、单标志法

int turn = init_num; //当前允许进入临界区的进程号
while(turn != num); //进入区
critical section; //临界区
turn = num + 1; //退出区
remainder section; //剩余区

在这里插入图片描述
这样的话,进程p0在访问临界区时,即使发生进程调度,p1进程的while也会一直循环,直到时间片用完。
在这里插入图片描述
但是单标志法有个缺点便是,当我改了turn的值,但是如果另一个进程一直不使用,标志位也没改过来,临界资源也处于空闲状态,那我也使用不了,因此不符合“空闲让进”原则。

2、双标志法

2.1 双标志先检查法

双标志法主要判断对方是否要进入临界区。

bool flag[2]; //表示进入临界区意愿的数组。
flag[0] = false;
flag[1] = false; //刚开始设置两个进程都不想进入临界区

P0进程
while(flag[1]); //当P1想进入临界区,P0会一直循环
flag[0] = true; // 标记P0进程想进入临界区(上锁)
critical section; //访问临界区
flag[0] = fasle; //访问完后,修改标记为P0不想使用临界区了(解锁)
remainder section;
P1进程
while(flag[0]);
flag[1] = true;
critical section;
flag[1] = fasle;
remainder section;

在这里插入图片描述

但是双标志法如果两个进程并发运行,此时当flag[1] = false, P0先跳出while循环,但是如果刚要执行flag[0] = true时,发生了调度/切换,进程P1开始访问,此时flag[0] = false,进程P1跳出while循环,那么继续执行flag[1] = true,开始进入临界区,但是此时又发生了切换,跳回P0进程,P0进程又将flag[0] = true,然后访问临界区,那么此时便会发生冲突。因此违反了“忙则等待”原则。

2.2 双标志后检查法

在这里插入图片描述
双标志先检查法先检查后上锁、双标志后检查法先上锁后检查。

3、peterson算法

bool flag[2]; //初始值都是false
turn = 0; // 优先让P0进程进入临界区
P0进程:
flag[0] = true;
turn = 1;
while(flag[1]&&turn = 1);
critical section;
flag[0] = false;
reminder section;
P1进程:
flag[1] = true;
turn = 0;
while(flag[0]&&turn = 0);
critical section;
flag[1] = false;
reminder section;

在这里插入图片描述
在这里插入图片描述
当进程无法进入临界区时,他还是一直再进行while循环,没有下CPU。
在这里插入图片描述

Ⅰ、三种算法对比

在这里插入图片描述

3.2 进程互斥的硬件实现方法

在这里插入图片描述

1、中断屏蔽方法

在这里插入图片描述
中断屏蔽方法并不适用多处理机操作系统,因为当在两个核同时进行关中断和开中断指令,也可能会导致同时对同一片临界区进行访问。而且这两个指令是特权指令,只能在内核态下运行。

2、TestAndSet指令(TS/TSL指令)

//布尔型共享变量lock表示当前临界区是否被加锁
//true表示已加锁,false表示未加锁
bool TestAndSet(bool *lock){
	bool old;
	old = *lock; //old用来存放lock原来的值
	*lock = true;//无论之前是否已加锁,都将lock设为true
	return old; //返回lock原来的值


while(TestAndSet(&lock)); //上锁并循环
critical section;
lock = false; //解锁
reminder section;

在这里插入图片描述

这里最重要的是理解,其实lock是共享性变量,当lock = true时,就是临界区有其他进程已经被上锁了,因此old返回的原来的变量也是true,而所以新进程只能陷入while循环。

3、Swap指令(XCHG指令)

在这里插入图片描述
在这里插入图片描述

3.3、互斥锁总结

在这里插入图片描述
在这里插入图片描述

四、信号量机制

4.1信号量

在这里插入图片描述

4.1.1整型信号量

这里以打印机为例,当打印机的数量为1时,定义整数型变量S = 1。当一个进程使用打印机时,先对其进行P(S),此时S经过修改已经为0,哪怕此时进行进程调度,有其他进行进程进来,由于S<=0,也仍然会陷入循环等待。只有当前进程在访问方程后V(S),S被修改为1。循环才会被跳过。
利用原语实现先检查后上锁。
在这里插入图片描述

4.1.2记录型信号量

在这里插入图片描述
举例说明记录行信号量的方法实现:首先假设有两台打印机,因此此时value = 2;S.L = 0;此时等待队列中没有阻塞的进程。当打印机分配给P0进程和P1进程后,此时value = 0;S.L = 0;而当一个P2进程时,首先执行wait(S),则value = -1,此时在wait中进行if判断,value<0,那么此时利用block原语使进程进入阻塞态,进入S.L等待队列。
因此,基于这样的判断,只要value<0,那么便代表着等待队列中有阻塞的进程正在等待,此时,当P0进程访问结束后,singel(S)释放资源,那么会进行该判断,判断完成后会从等待队列中利用wakeup原语唤醒一个阻塞态的进程,使其变为就绪态,等待调度。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

4.2 信号量机制实现进程同步与互斥。

4.2.1 实现进程互斥

在这里插入图片描述
PV原语必须成对出现。
在这里插入图片描述

4.2.2实现进程同步

实现进程同步,首先要设置一个同步信号量,其次,要在具有先后顺序的操作,“前操作”之后执行V(S)操作,"后操作"之前执行P(S)操作。(V释放资源,P申请资源)
假设代码2必须在代码4之前执行,具体过程如下:
在这里插入图片描述

4.2.3 信号量机制实现前驱关系

在这里插入图片描述

五、生产者消费者问题

5.1问题描述

在这里插入图片描述
生产者消费者问题:
(1)对于同步关系:
首先必须对每个操作都设置一个同步信号量;其次前后关系为:缓冲区便必须有产品,消费者才能消费,要不消费进程会进入阻塞态。因此“前V后P”在缓冲区有产品的后面加上V(full),消费者消费前加上P(S)。而只有当缓冲区没满时,生产者才能一直生产,要不然就会阻塞,因此在缓冲区没满后加上V(empty),生产者生产前加上P(empty)。
(2)对于互斥关系
设置互斥信号量mutex = 1;在临界区的前后实现PV操作即可。

在这里插入图片描述

5.2问题实现

1、信号量设置:

typedef struct{
	int value; //资源数
	struct process *L; //等待队列
	}semaphore;
semaphore full = 0; //同步信号量
//刚开始缓冲区没有资源(产品),因此信号量为0
semaphore empty = n;//同步信号量
//空闲缓冲区资源数,即缓冲区有n个空位
semaphore mutex = 1;//互斥信号量

2、生产者生产与消费者消费

生产者生产:

producer(){
	while(1){
	生产一个产品;
	P(empty);//消耗一个空闲缓冲区
	P(mutex); //互斥访问mutex-1
	将产品放入缓冲区;
	V(mutex); //互斥访问mutex+1
	//此时使用PV原语实现互斥访问,
	//即查看当前缓冲区是否有其他进程往里面放产品
	V(full); //增加一个资源
	}
}

消费者消费:

consumer(){
	while(1){
	P(full); //消耗一个产品
	P(mutex); //mutex - 1=0上锁
	从缓冲区取一个产品;
	V(empty); //增加一个空闲位
	P(mutex); //互斥访问 mutex+1=1解锁
	//同一时刻只能由一个消费者进行消费
	使用产品;
	}
}

在这里插入图片描述
两个P操作顺序不能颠倒,颠倒会陷入死锁。V操作可以。实现互斥的P操作一定要在实现同步的P操作之后。
在这里插入图片描述
在这里插入图片描述

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值