# 生产者 - 消费者问题

在进程同步中第一个问题就是生产者 - 消费者问题,首先我们利用记录型信号来分析这个问题。

好好好,我们直接伪代码解析!

解释在行代码的上方

详细伪代码
//in 代表下一个要写入的位置,out 代表要读取的位置
int in = 0,out = 0;
// 用于存储生产者生产的容器,可以理解为缓冲区
item buffer[n];
// 前两行不是重点,下面才是核心!!
//mutex 用于互斥访问共享资源,初值必须为 1(可以理解为锁)
//empty 代表中转的容量,初值为最大承载容量,题里会给(可以是各种容器)
//full 是生产出的一种逻辑 / 实体的物质
// 总之不管是什么他是生产者生产出来的,一开始还没生产,full 初值为 0
semaphore mutex = 1,empty = n,full = 0;
// 生产者逻辑
void producer(){
    //do-while 死循环,不断生产,配合消费者模拟程序并发
    do{
        // 生产一个产品
        produce an item nextp;
        ...
        //wait 什么什么就是什么什么 “--”,比如这里 wait (empty) 就是 empty--
        // 相当于空位置减一,申请一个缓冲区
        wait(empty);
        // 相当于加锁,申请缓冲区的使用权
        wait(mutex);
        // 将产品放入缓冲区之中
        buffer[in] = nextp;
        // 下一个缓冲区的地址
        in = (in + 1) % n;
        //signal 什么什么就是什么什么 “++”,比如这里 signal (mutex) 就是 empty++
        // 解锁,相当于释放权限
        signal(mutex);
        // 生产的东西数量加 1,也就是释放缓冲区
        signal(full);
    }while(true);
}
// 消费者逻辑
void consumer(){
    //do-while 死循环,不断生消费,配合生产者模拟程序并发
    do{
        // 消费者要消费一个物质,将生产者的生产的 full--
        wait(full);
        // 加锁,mutex--
        wait(mutex);
        // 其实这里不用太深究,这里就是消费者从缓冲区拿走了一个生产者的生产的物质
        // 从缓冲区中取出产品
        nextc = buffer[out];
        // 导向下一个缓冲区的地址
        out = (out + 1) % n;
        // 解锁,mutex++
        signal(mutex);
        // 消费者已经取走了,空位置 empty++
        signal(empty);
        // 消费者消费物质
        consume the item nextc;
        ...
    }while(true)
}
void main(){
    cobegin
    producer();consumer()
    coend
}

简单的写法:

简单伪代码
Producer():
  Repeat
    生产一个商品
    wait(empty);
    wait(mutex);
    将商品送至缓冲区;
    signal(mutex);
    signal(full);
  Until false
Comsumer():
  Repeat
    wait(full);
    wait(mutex);
    从缓冲区取走一个物品
    singal(mutex);
    signal(empty);
  Until false
Program main()
  empty,full,mutex;
    begin
      empty = n;
      full = 0;
      mutex = 1;
      cobegin
        producer();consumer();
      coend
    end

# 练习一下!

桌上有个能盛得下五个水果的空子。爸爸不停地向盘中放苹果或橘子,儿子不停地从盘中取出桔子享用,女儿不停地从盘中取出苹果享用。规定三人不能同时从盘子中取放水果。使用信号量实现爸爸、儿子和女儿这三个循环进程之间的同步。

empty = 5,orange = 0,apple = 0,mutex = 1;
Dad(){
    while(1){
        wait(empty);
        wait(mutex);
        将水果放入盘中;
        signal(mutex);
        if(放了橘子) signal(orange);
        else signal(apple);
    }
}
Son(){
    while(1){
        wait(orange);
        wait(mutex);
        拿走一个桔子;
        signal(mutex);
        signal(empty);
        吃桔子;
    }
}
Daughter(){
    while(1){
        wait(apple);
        wait(mutex);
        拿一个苹果;
        signal(mutex);
        signal(empty);
        吃苹果;
    }
}
更新于 阅读次数

请我喝[茶]~( ̄▽ ̄)~*

KarryLiu 微信支付

微信支付

KarryLiu 支付宝

支付宝