N 个生产者进程和 M 个消费者进程共享大小为 K 的缓冲区

电子科技大学考研题目:
M个生产者进程和 N个消费者进程共享大小为 K 的缓冲区,遵循规则如下:
(1) 进程之间必须以互斥方式访问缓冲区;
(2) 对每 1 条放入缓冲区的数据,所有消费者都必须接收 1 次;
(3) 缓冲区满时,生产者必须阻塞;
(4) 缓冲区空时,消费者必须阻塞。
请用 P、V 操作实现其同步过程,须说明信号量含义。
 

分析,根据规则:

规则一,进程间互斥访问缓冲区,K个缓冲区需要 K 个信息量,初始化时缓冲区是可以访问的。

规则三,缓冲区满时,生产者需要阻塞,也就是当前每个缓冲区占用时,生产者阻塞。只要有空缓冲区生产者就可以生产,因为生产者不能等待某个具体的缓冲区,需要设置一个初始值为 K 的信号量来控制生产者是否能够进行生产。

规则二、四是实现对消费者的阻塞,只要控制每个消费者的消费数即默认实现了规则四。

因为每个消费者都要读一遍数据,所以生产每生产一个产品需要增加所有消费者的消费量,另外需要设置一个消费者是否读取数据的计数矩阵,以确定最后一个数据读取者读完数据量,增加生产者可以缓冲区数。

 

写了一段代码如下,未仔细验证仅供参考:

semaphore buff_mutex[K] = {1};    // 缓冲区 0~K 读写信号量
semaphore empty_mutex = K;        // 空缓冲区信号量, 0-缓冲区满,生产者互斥

semaphore read_mutex[M] = {0};    // 消费者可用消息数信号量

buffer  buffer[K] = {NULL};
bool  buff_read[K][M] = {1};    // 初始化每个消费者每个缓存位置都读过

producer()
{
    int i,j;
    while (1) {
        // 实现满队列等待
        P(empty_mutex);
        for(i=0; i<K; i++){
            // 实现写进程的互斥
            P(buff_mutex[i]);
            if(buffer[i] == NULL){
                buffer[i] = get_new_message();
                for(j=0; j<M; j++){
                    // 置每个消息未读取
                    buff_read[i][j]=0;
                    // 增加每个消费者消息数,激活消费者
                    V(read_mutex[j]);
                }
            }
            V(buff_mutex[i]);
            sleep(random(1)); // 随机等待以调度其它生产者
        }
    }
}

                    
consumer(no)   // no 是消费者编号
{
    int i,j;
    buffer read_message;
    
    while(1){
        read_message = NULL;
        // 消费者有消息读取
        P(read_mutex[no]);
        for(i=0; i<K; i++){
            P(buff_mutex[i]);
            if(buffer[i][no] == 0){
                read_message=buffer[i]      // 读取消息
                buff_read[i][no] = 1
                for(j=0; j<M; j++){
                    // 判断是否全读消费者都读取消息
                    if(buffer[i][j] == 0){
                        break;
                    }
                }
                if(j>=M){                    // 所有消费者读完信息
                    buffer[i] = NULL;
                    V(empty_mutex);         // 激活生产者
                }
            }
            V(buff_mutex[i]);
            if(read_message){
                // 读到消息了,跳出循环,保证未读消息数量正确
                break;
            }
        }
    }
}

  • 4
    点赞
  • 28
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
这是一个典型的生产者消费者问题。为了实现这个问题,我们需要使用线程同步的机制,例如信号量或互斥锁,以确保生产者消费者进程之间的正确协作。 具体实现方法如下: 1. 创建一个数组来表示缓冲区,初始化为空。 2. 创建两个计数器:producerCount 和 consumerCount,分别表示当前缓冲区中有多少个生产者消费者进程在等待。 3. 创建两个信号量:empty 和 full,分别表示缓冲区是否为空和是否已满。 4. 创建一个互斥锁 mutex,用于保护缓冲区的访问。 5. 生产者进程:当缓冲区不满时,向缓冲区中加入一个新的数据项,同时通知消费者进程缓冲区中已经有新的数据项可供消费。 6. 消费者进程:当缓冲区不为空时,从缓冲区中取出一个数据项,同时通知生产者进程缓冲区中已经有一个空位可供生产。 7. 当缓冲区已满时,生产者进程需要等待,直到有空位可供生产。此时,producerCount 自增,并且生产者进程进入等待状态。 8. 当缓冲区为空时,消费者进程需要等待,直到有数据可供消费。此时,consumerCount 自增,并且消费者进程进入等待状态。 9. 当生产者进程缓冲区中加入一个新的数据项时,如果有消费者进程在等待,则唤醒其中一个消费者进程,并且 consumerCount 自减。 10. 当消费者进程缓冲区中取出一个数据项时,如果有生产者进程在等待,则唤醒其中一个生产者进程,并且 producerCount 自减。 11. 为了保护缓冲区的访问,每个进程在访问缓冲区之前需要先申请 mutex 互斥锁,操作完成之后再释放该锁。 12. 当程序结束时,需要释放所有的信号量和互斥锁。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

Leon-2012

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

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

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

打赏作者

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

抵扣说明:

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

余额充值