【考研】操作系统:2014年真题47(同步互斥问题)

34 篇文章 52 订阅
23 篇文章 9 订阅

前言

解决同步互斥问题的思路,源于对王道讲解的总结笔记

同类型题目:

【考研】操作系统:2019年真题43(同步互斥问题)_住在阳光的心里的博客-CSDN博客

【考研】操作系统:2015年真题45(同步互斥问题)_住在阳光的心里的博客-CSDN博客

【考研】操作系统:2009年真题45(同步互斥问题)_住在阳光的心里的博客-CSDN博客

2014年真题47,是生产者-消费者经典问题的变型,可先参考学习生产者-消费者经典问题。

OS知识点汇总(考研用)——第二章:进程管理(下)_左职新手的博客-CSDN博客

一、思路

解决同步互斥问题,思路步骤:

1. 分析各进程之间的同步互斥关系;

2. 设置互斥信号量 mutex = 1、同步信号量(一般设可使用的资源数为empty = N)。

3. 最好画出同步互斥关系图,并判断属于哪一种类型,如生产者-消费者问题、读者-写者问题、哲学家进餐问题、吸烟者问题。

二、题目

45. 系统中有多个生产者进程和消费者进程,共享用一个可以存 1000 个产品的环形缓冲区(初始为空),当缓冲区为未满时,生产者进程可以放入一件其生产的产品,否则等待;当缓冲区为未空时, 消费者进程可以取走一件产品, 否则等待。 要求一个消费者进程从缓冲区连续取出 10件产品后,其他消费者进程才可以取产品,请用信号量 P, V( wait , signed )操作实现进程间的互斥和同步,要求写出完整的过程;并指出所用信号量的含义和初值。

解:(1)互斥资源:

一个消费者进程从缓冲区连续取出 10件产品后,其他消费者进程才可取产品,设置互斥信号量 mutex1 = 1;

生产者和消费者对缓冲区的访问进行设置互斥信号量:mutex2 = 1;

(2)同步关系:生产者和消费者进程共享用一个可以存 1000 个产品的缓冲区(初始为空),则设同步信号量 empty = 1000,代表有几个空闲缓冲单元; 设同步信号量 full = 0,代表此时缓冲区的产品数; 

 (3)同步互斥关系图如下:(生产者-消费者的变型)

(4)伪代码如下:

第一步:设置信号量

semaphore mutex1 = 1;
semaphore mutex2 = 1; 
semaphore empty = 1000;  // 有几个空闲缓冲单元
semaphore full = 0;

第二步:首先确定是生产者-消费者的问题,列出如下伪代码 

producer(){
    while(1){
        生产一个产品;
        把产品放入缓冲区;
    }
}

consumer(){
    while(1){
        从缓冲区取出一件产品;
        消费这件产品;
    }
}

第三步:再设置进程单次互斥访问缓冲区

producer(){
    while(1){
        生产一个产品;
        
        P(mutex2);
        把产品放入缓冲区;
        V(mutex2);
    }
}

consumer(){
    while(1){

        P(mutex2);
        从缓冲区取出一件产品;
        V(mutex2);

        消费这件产品;
        
    }
}

第四步:生产者:放产品前判断缓冲区是否有空位;消费者:取出产品后再腾出空位。

producer(){
    while(1){
        生产一个产品;
        
        P(empty);  // 判断缓冲区是否有空位

        P(mutex2);
        把产品放入缓冲区;
        V(mutex2);
    }
}

consumer(){
    while(1){

        P(mutex2);
        从缓冲区取出一件产品;
        V(mutex2);
        
        V(empty);  // 取出产品后再腾出空位

        消费这件产品;
        
    }
}

第五步:在生产者生产一个产品后,此时缓冲区的产品数加一;在消费者使用一个产品后,此时缓冲区的产品数减一;

producer(){
    while(1){
        生产一个产品;
        
        P(empty);  // 判断缓冲区是否有空位

        P(mutex2);
        把产品放入缓冲区;
        V(mutex2);

        V(full);   // 缓冲区产品数加一
    }
}

consumer(){
    while(1){
        P(full);   // 缓冲区产品数减一

        P(mutex2);
        从缓冲区取出一件产品;
        V(mutex2);
        
        V(empty);  // 取出产品后再腾出空位

        消费这件产品;
        
    }
}

第六步:与经典的生产者-消费者问题的不同在于,要求一个消费者进程从缓冲区连续取出 10件产品后,其他消费者进程才可取产品。

所以,用互斥信号mutex1来实现消费者之间的制约, 用 for 循环来实现一个消费者连续取10次后,下一个消费者才可从缓冲区取产品。

producer(){
    while(1){
        生产一个产品;
        
        P(empty);  // 判断缓冲区是否有空位

        P(mutex2);
        把产品放入缓冲区;
        V(mutex2);

        V(full);   // 缓冲区产品数加一
    }
}

consumer(){
    while(1){
        P(mutex1);   // 设置互斥信号量,实现一个消费者进程一个周期(10次)内次对缓冲区的控制
            for(int i = 0; i < 10; i++){   // 用 for 循环实现连续取 10 次
                P(full);   // 缓冲区产品数减一

                P(mutex2);
                从缓冲区取出一件产品;
                V(mutex2);
            
                V(empty);  // 取出产品后再腾出空位
    
                消费这件产品;
            }
        V(mutex1);  
    }
}

完整代码如下:

semaphore mutex1 = 1;
semaphore mutex2 = 1; 
semaphore empty = 1000;  // 有几个空闲缓冲单元
semaphore full = 0;

producer(){
    while(1){
        生产一个产品;
        
        P(empty);  // 判断缓冲区是否有空位

        P(mutex2);
        把产品放入缓冲区;
        V(mutex2);

        V(full);   // 缓冲区产品数加一
    }
}

consumer(){
    while(1){
        P(mutex1);   // 设置互斥信号量,实现一个消费者进程一个周期(10次)内次对缓冲区的控制
            for(int i = 0; i < 10; i++){   // 用 for 循环实现连续取 10 次
                P(full);   // 缓冲区产品数减一

                P(mutex2);
                从缓冲区取出一件产品;
                V(mutex2);
            
                V(empty);  // 取出产品后再腾出空位
    
                消费这件产品;
            }
        V(mutex1);  
    }
}

三、进一步理解

系统中有多个生产者进程和消费者进程,共享用一个可以存 1000 个产品的环形缓冲区(初始为空)。

环形缓冲区,相当于一个循环队列。可以设置一个大小为1000的循环缓冲区。

 在本题里,不用再额外判断循环队列是否“满 / 空”,因为设置了 P(mutex) 和 P(full) 来分别判断缓冲区是否有空位,缓冲区是否有产品。

备注:判断栈、队列为 “ 满 / 空 ” 和其长度。

长度
s->top == maxsize - 1;

s->top == -1;

顺序栈:s->top == s->base;
链栈:s->next == NULL

s->top + 1;
队列(Q.rear + 1) % maxsize == Q.front

Q.front == Q.rear == 0
 

链队:
if(Q.rear == NULL) return 1;

(rear - front + maxsize) % maxsize

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

住在阳光的心里

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值