基于环形队列的生产者消费者模型编写。

1. 环形队列
在队列为空时,生产者必须先运行,消费者不能越过生产者
在队列为满时,消费者先运行,生产者不能超过消费者一圈,
不能同时访问同一位置:
2. 信号量
    sem_t sem;//POSIX的线程标准下的
    信号量机制通过信号量的值控制可用资源的数量。线程访问共享资源前,需要申请获取一个信号量,如果信号量为0,说明当前无可用的资源,线程无法获取信号量,则该线程会等待其他资源释放信号量(信号量加1)。如果信号量不为0,说明当前有可用的资源,此时线程占用一个资源,对应信号量减1。
    举例:
    停车场有5个停车位,汽车可使用停车位。在这里5个停车位是共享的资源,汽车是线程。开始信号量为5,表明此时有5个停车位可用。一辆汽车进入停车场前,先查询信号量的值,不为0表明有可用停车位,汽车进入停车场并使用一个停车位,信号量减1,表明占用一个停车位,可用数减少。
    信号量初始化函数:
    int sem_init(sem_t *sem, int pshared, unsigned int value);
    sem: 信号量
    pshared:参数表示这个信号量是否在进程的线程之间共享进程之间
    value:初始值 
    nt sem_wait(sem_t *sem);
    该函数申请一个信号量,当前无可用信号量则等待,有可用信号量时占用一个信号量,对信号量的值减1。
    信号量加1:
    int sem_post(sem_t *sem);
    该函数释放一个信号量,信号量的值加1。
    销毁信号量:
    int sem_destory(sem_t *sem);
    该函数销毁信号量。
    sem_init(&blankSem, 0, SIZE);//初始化
    sem_init(&dataSem, 0, 0);
3.临界资源
创建全局数组 int ring[SIZE] = 0;

这里写图片描述
这样信号量不仅可以实现生产者与消费者的同步,而且可以实现互斥(两者不可能同时访问同一资源);

1. 基于环形队列的单生产者单消费者模型

void* product(void *arg)//生产者
{
    int i = 0;
    int n = 0;
    while(1)
    {
        sem_wait(&blankSem);//申请格子放数据
        ring[i] = n++;//减一成功后,放数据
        sem_post(&dataSem);//数据放完成后,数据数目加1,
        printf("product doing! %d\n",ring[i++]);

        i = i%SIZE;
    }
    return NULL;
}
void* consume(void *arg) //消费者
{
    int i = 0;
    int data = 0;
    while(1)
    {   sem_wait(&dataSem);//请求拿数据,阻塞方式
        data = ring[i]; //
        sem_post(&blankSem);//拿到数据后,空格加1
        printf("consume doing %d\n",data);
        sleep(1);
        i++;
        i = i%SIZE;//实现环形
    }
}

2. 基于环形队列的多生产者多消费者模型编写。

信号量只能实现生产者与消费者之间的·互斥·同步·
现在多生产者和消费者,所以需要加入,互斥锁实现生产者与生产者之间的互斥,消费者与消费者之间的互斥;
int i = 0int n = 0;
int data = 0; 
void* product_1(void *arg)//生产者1
{
    while(1)
    {
        pthread_mutex_lock(&lock_2); 
        //信号量在生产者之间是临界资源,所以在互斥锁加解之间
        sem_wait(&blankSem);//申请放数据
        ring[i] = n++;
        sem_post(&dataSem);//放完数据,增加数据数目
        printf("product_1 doing! %d\n",ring[i++]);      
        i = i%SIZE;
        pthread_mutex_unlock(&lock_2);//解锁
        sleep(1);
    }
    return NULL;
}
void* product_2(void *arg)//生产者2
{
    while(1)
    {
        pthread_mutex_lock(&lock_2);//解锁
        sem_wait(&blankSem);
        ring[i] = n++;
        sem_post(&dataSem);
        printf("product_2 doing! %d\n",ring[i++]);      
        i = i%SIZE;
        pthread_mutex_unlock(&lock_2);
        sleep(1);
    }
    return NULL;
}
void* consume_1(void *arg)//消费者1
{
    int data = 0;
    while(1)
    {
        pthread_mutex_lock(&lock_1);//解锁
        sem_wait(&dataSem);//申请拿数据
        data = ring[con]; 
        sem_post(&blankSem);//拿数据后,增加空格数目
        printf("consume_1 doing %d\n",data);
        sleep(1);
        con++;
        con = con%SIZE;
        pthread_mutex_unlock(&lock_1);//解锁
        sleep(2);
    }
    return NULL;
}
void* consume_2(void *arg)//消费者2
{
    int data = 0;
    while(1)
    {
        pthread_mutex_lock(&lock_1);
        sem_wait(&dataSem);
        data = ring[con]; 
        sem_post(&blankSem);
        printf("consume_2 doing %d\n",data);
        sleep(1);
        con++;
        con = con%SIZE;
        pthread_mutex_unlock(&lock_1);
        sleep(2);
    }
        return NULL;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值