操作系统---信号量

本文详细介绍了使用信号量解决并发控制的问题,包括设置信号量、实现进程互斥和前趋关系。通过生产者-消费者问题、哲学家进餐问题和读者-写者问题的实例,阐述了P、V操作在不同场景下的应用,强调了在多进程中的互斥和同步策略。同时,总结了P、V操作中信号量的正确使用方式。
摘要由CSDN通过智能技术生成

1. 用信号量解题步骤:(1)设置信号量(2)给信号量赋初值(3)P、V操作安排位置

2. 信号量实现进程互斥

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

2.1 互斥信号量取值范围
例:两个进程,取值范围(-1,0,1)
m个进程,取值范围(1-m,1)

3. 信号量实现前趋关系

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

例如:
在这里插入图片描述
解答: a = V(S1); V(S2)
b = P(S1)
c = P(S2) ;P(S3)
d = p(S4)

4. 初始状态下:empter = 1,因为缓冲区“空”的位置有,所以为1;full = 0,因为缓冲器“满”的位置没有,所以为0.

5. 生产者–消费者问题

分析问题里有几个进程;分析之间存在互斥模式还是同步模式,例:生产者–消费者问题是互斥模式和同步模式;
(1)一个生产者,一个消费者,共用一个缓冲区
在这里插入图片描述
代码:
void producer( ) {
while(true) {
生产一个产品;
P(empty);
产品送往Buffer;
V(full);
}
}
void consumer( ) {
while(true) {
P(full);
从Buffer取出一个产品;
V(empty);
消费该产品;
}
}
(2)一个生产者,一个消费者,公用n个环形缓冲区
在这里插入图片描述
代码:
void producer() {
while(true) {
生产一个产品;
P(empty);//申请一个空缓冲区
buffer[in] =nextp;
in=(in+1)% n;
V(full); //释放一个满缓冲区
}
}
void consumer() {
while(true) {
P(full); //申请一个满缓冲区
nextc = buffer[out];
out = (out+1)%n;
V(empty); //释放一个空缓冲区
消费该产品;
}
}
(3) 一组生产者,一组消费者,公用n个环形缓冲区
在这里插入图片描述
为什么存在互斥问题:
在这个问题中,不仅生产者与消费者之间要同步,而且各个生产者之间、各个消费者之间还必须互斥地访问缓冲区。
代码:
void producer() {
while(true) {
生产一个产品;
P(empty); //申请一个空缓冲区
P(mutex1); //申请空缓冲区使用权
buffer[in] =nextp;
in=(in+1)% n;
V(mutex1); //释放空缓冲区使用权
V(full); //释放一个满缓冲区
}
}
void consumer() {
while(true) {
P(full);
P(mutex2);
nextc = buffer[out];
out = (out+1)%n;
V(mutex2);
V(empty);
消费该产品;
}
}

6. 哲学家进餐

在这里插入图片描述
定义互斥信号量组,筷子是临界资源,初始值为1
代码:
semaphore chopstick[5] = {1,1,1,1,1};
do{
wait(chopstick[i]); //先取左手的筷子 左手的筷子都能拿起,但都不释放
wait(chopstick[(i+1)%5]); //再取右手的筷子

//eat

signal(chopstick[i]);
signal(chopstick[(i+1)%5]);

//think

}while(TRUE);
在这里插入图片描述
(1)
semaphore chopstick[5] = {1,1,1,1,1};
semaphore count=4;
do{
wait(count);
wait(chopstick[i]);
wait(chopstick[(i+1)%5]);
eat();
signal(chopstick[i]);
signal(chopstick[(i+1)%5]);
signal(count);
think();
}while(TRUE);
3号先吃,然后2号,1号,0号,4号
(2)
semaphore chopstick[5] = {1,1,1,1,1};
do{
Swait(chopstick[i], chopstick[(i+1)%5]);
eat();
Ssignal(chopstick[i], chopstick[(i+1)%5]);
think();
}while(TRUE);
0号,2号,1号,3号,4号
(3)
semaphore chopstick[5] = {1,1,1,1,1};
do{
if(i%2==1)
{
P(chopstick[i]);
P(chopstick[(i+1)%5]);
eat();
V(chopstick[i]);
V(chopstick[(i+1)%5]);
think();
}
else{
P(chopstick[(i+1)%5]);
P(chopstick[i]);
eat();
V(chopstick[i]);
V(chopstick[(i+1)%5]);
think();
}
}while(TRUE);
0号,2号,1号,3号,4号

7. 读者–写者问题

类型:读、读共享,读、写互斥,写、写互斥。
互斥信号量,Readcount:表示正在读的进程数目
读操作的时候顺便把写操作也占用
在这里插入图片描述

8. 总结:P、V操作中何时该做的操作

一般情况下,empty=1,full=0。当进行wait操作时,就是要申请一个位置,因为empty=1,所以写empty,这样的话empty=1-1=0;然后进行signal操作的时候,就是释放一个位置,所以full=0+1=1。
也就是说,wait里填写的是不为0的值,signal里填写的是值为0的

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值