采用信号量机制实现消费者与生产者的线程同步_经典生产者-消费者问题解析...

1.生产者-消费者问题

生产者和消费者问题在现实系统中是很普遍的。例如在一个多媒体系统中,生产者编码视频帧,而消费者消费(解码)视频帧,缓冲区的目的就是减少视频流的抖动。又如在图形用户接口设计中,生产者检测到鼠标和键盘事件,并将其插入到缓冲区中。消费者以某种基于优先级的方式从缓冲区中取出这些事件并显示在屏幕上。

生产者和消费者模式共享一个有n个槽位的有限缓冲区。生产者反复地生成新的item,并将它插入到缓冲区中。消费者不断从缓冲区中取出这些item,并消费它们。它有3个显著特点:

  • 因为生产和消费都涉及共享变量的更新,所以必须保证对缓冲区的访问是互斥的。
  • 如果缓冲区是满的,那么生产者必须等待直到有一个槽位可用。
  • 如果缓冲区是空的,那么消费者必须等待直到有一个item可以。

下文将开发一个简单的生产者消费者包SBUF,它操作类型为sbuf_t的有限缓冲区。item存放在一个动态分配的容量为n的整数数组buf中。索引值front和rear分别指向数组的首尾项。三个信号量同步对缓冲区的访问。mutex信号量提供互斥访问,slotsitems信号量分别记录空槽位和可用item的数量。

typedef struct{
    
    int *buf;       //缓冲区指针(指向一个数组)
    int n;          //最大空槽位数量(缓冲区大小)
    int front;      //指向数组第一个item,即buf[(front+1)%n]
    int rear;       //指向数组最后一个item,即buf[rear%n]
    sem_t mutex;    //缓冲区互斥锁
    sem_t slots;    //可用槽位数
    sem_t items;    //可用item数
}sbuf_t;
Posix标准定义的信号量操作函数:
```c
include
int sem_init(sem_t sem, 0, unsigned int value); int sem_wait(sem_t s); //等价于P(s) int sem_post(sem_t *s); //等价于V(s) ```

下文继续给出SBUF包实现的代码:

  • sbuf_init函数初始化一个缓冲区,在其它任意函数前被调用;
  • sbuf_deinit函数释放一个缓冲区,在其它任意函数后被调用;
  • sbuf_insert函数等待一个可用槽位并添加item;
  • sbuf_remove函数等待并消费一个item;
/* $begin sbufc */
#include "csapp.h"
#include "sbuf.h"

/* Create an empty, bounded, shared FIFO buffer with n slots */
/* $begin sbuf_init */
void sbuf_init(sbuf_t *sp, int n)
{
    
    sp->buf = Calloc(n, sizeof(int)); 
    sp->n = n;                       /* Buffer holds max of n items */
    sp->front = sp->rear = 0;        /* Empty buffer iff front == rear */
    Sem_init(&sp->mutex, 0, 1);      /* Binary semaphore for locking 
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值