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

本文介绍了生产者-消费者问题和读者-写者问题的经典同步解决方案,通过信号量机制确保对共享资源的线程安全访问。在生产者-消费者问题中,展示了如何实现SBUF包,包括初始化、插入和移除item的函数。接着,讨论了读者-写者问题,提出了读者优先的策略,并解释了如何通过互斥锁确保并发访问的正确性。最后,阐述了预线程化并发服务器的实现,该服务器由主线程和工作者线程组成,使用共享缓冲区进行通信。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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 */
    Sem_init(&sp->slots, 0, n);      /* Initially, buf has n empty slots */
    Sem
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值