深入理解计算机系统-----生产者消费者程序

版权声明: https://blog.csdn.net/zl6481033/article/details/88102272

1、实现代码

#include "sbuf.h"
#include "csapp.h" 
typedef struct{
     int *buf;
     int n;
     int front;
     int rear;
     sem_t mutex;
     sem_t solts;
     sem_t items;
 }sbuf_t;


//初始化,分配内存,初始化信号
void sbuf_init(sbuf_t *sp,int n)
{
    sp->buf = Calloc(n,sizeof(int));
    sp->n = n;
    sp->front = sp->rear = 0;
    Sem_init(&sp->mutex,0,1);
    Sem_init(&sp->slots,0,n);
    Sem_init(&sp->items,0,0);
}

//释放缓冲区
void sbuf_deinit(sbuf_t *sp)
{
    Free(sp->buf);
}
//添加项目
void sbuf_insert(sbuf_t *sp,int item)
{
    P(&sp->slots);
    P(&sp->mutex);
    sp->buf[(++sp->rear)%(sp->n)]=item;
    V(&sp->mutex);
    V(&sp->items);
}
//取出项目
void sbuf_remove(sbuf_t *sp)
{
    int item;
    P(&sp->item);
    P(&sp->mutex);
    item = sp->buf[(++sp->front)%(sp->n)];
    V(&sp->mutex);
    V(&sp->slots);
    return item;
}

2、代码分析

        SBUF操作类型为sbuf_t的有限缓冲区,项目存放在一个动态分配的n项整数数组中,front和rear索引值记录该数组的第一项和最后一项,三个信号量同步对缓冲区的访问,mutex信号量提供互斥的缓冲区的访问,slots和items信号量分贝纪录空槽位和可用项目的数量。

        sbuf_init函数为缓冲区分配堆内存,设置front和rear表示一个空的缓冲区,并为三个信号量赋初值,这个函数在调用其他三个函数中任何一个之前调用一次,sbuf_deinit函数是当应用程序使用完缓冲区时,释放缓冲区存储的。sbuf_insert函数等待一个可用的槽位,对互斥锁加锁,添加项目,对互斥锁解锁,然后宣布有一个新的项目可用。sbuf_remove函数与sbuf_insert函数对称,等待一个可用的缓冲区项目之后,对互斥锁加锁,从缓冲区的前面取出该项目,对互斥锁解锁,然后发信号通知一个新的槽位可供使用。

猜你喜欢

转载自blog.csdn.net/zl6481033/article/details/88102272