进程间通信经典问题(一 生产者消费者问题)

一 消费者——生产者问题

1 思路:两个进程共享一个公共的固定大小的缓冲区,其中一个是生产者将信息放入缓冲区,另外一个是消费者,从缓冲区取出信息。当缓冲区已满,此时生产者还想向其中放入一个新的数据项,解决办法是让生产者睡眠,待消费者从缓冲区取出一个或者多个数据时再唤醒它。同样,当消费者从缓冲区取出数据时发现缓冲区为空时,消费者就睡眠,直到生产者向其中放入一些数据时再将其唤醒。

解法一

#define N100//缓冲区中的槽目数
int count =0;//缓冲区中的数据项目

void producer(void)
{
    int item;

    while (TRUE)//无限循环
{
    item =produce_item();//产生下一新数据项
    if(count==N)sleep();//如果缓冲区满了,就进入休眠状态
    inert_item(item);//将新数据项放入缓冲区中
    count=count+1;//将缓冲区中的数据项计数器加一
    if(count==1)wakeup(consumer);//判断缓冲区是否为空
} 
}

    void consumer(void)
{
    int item;
    while (TRUE)    //无线循环
{
    if (count==0)sleep();//如果缓冲区空,则进入休眠状态
    item =remove_item();//从缓冲区中取出一个数据项
    count =count-1;//将缓冲区中的数据项计数器减一
    if(count ==N-1)wakeup (producer);//判断缓冲区是否已满
    consume_item(item);//打印数据项
}
}

2 缺点: (导致生产者进程跟消费者进程同时永远休眠下去)对count 的访问没有限制有可能造成:缓冲区为空,消费者刚读取 count值为零,此时调度程序决定暂停消费者并唤醒生产者。生产者向缓冲区加入一个数据项,count加一,当count变成1时进程推断认为之前的count为0,发现count为零时候消费者进程进入睡眠,于是生产者进程占满了整个缓冲区,然后睡眠。

3 解决方法:加入一个唤醒等待位

解法二

利用信号量解决生产者消费者问题

1 解决思路 :使用三个信号量:

一个称为full,用于记录充满的缓冲槽数目,

一个称为empty,记录空的缓冲槽数目,

一个称为mutex,用来确保生产者和消费者不会同时访问缓冲区 

full的初值为0 empty初值为缓冲槽中的槽数目,mutex初始为1 供两个或者多个进程使用的信号量,其初始值为1 保证同时只有一个进程进入临界区,称为二元信号量,每个进程在进入临界区都执行一个down操作,退出时执行一个up操作,实现互斥。

#define N 100//缓冲区中的槽数目
typedef int semaphore;//信号量是一种特殊的整型数据
semaphore mutex = 1;//控制对临界区的访问
semaphore empty = N;//计数缓冲区的空槽数目
semaphore full = 0;//计数缓冲区的满槽数目

void produce (void)
{
    int item;
    
    while(TRUE)//TURE为常量1
{
    item = produce_item();//产生放在缓冲区中的一些数据
    down(&empty);//将空槽数目减一
    down(&mutex);//进入临界区
    insert_item(item);//将新数据项放入缓冲区
    up(&mutex);//离开临界区
    up(&full);//将满槽数目加1
}
}

void consume(void)
{
    int item;

    while(TURE)//无限循环
{
    down(&full);//满槽数目加一
    down(&mutex);//进入临界区
    item =remove_item();//从缓冲区取出数据项
    up(&mutex);//离开临界区
    up(&empty);//将空槽数目加一
    consume_item(item);//处理数据项
}
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值