C++实现生产者和消费者问题(linux环境下)

/*
 * @Author: szq 
 * @Date: 2020-07-06 18:13:23 
 * @Last Modified by: szq
 * @Last Modified time: 2020-07-06 19:19:25
 * @Descripution:在Linux上面实现生产者和消费者问题
 */


/**
 * 问题描述:生产者向缓冲区中添加数据,消费者从缓冲区中拿数据。缓冲区这里设置为5.
 * 限制条件:1.同时只能有一个生产者向缓冲区中添加数据,并且当缓冲区满的时候,不能再向缓冲区添加数据
 *                          2.同时只能有一个消费者能从缓冲区拿数据,并且当缓冲区为空时,不能再从缓冲区内拿数据.
 * 
*/

#include<iostream>
#include<mutex>
#include<semaphore.h>
// #include<thread>
#include<pthread.h>
using namespace std;

//创建一个信号量,用来实现临界区的互斥
mutex m;

//创建生产者的信号量
sem_t empty ;
//创建消费者的信号量
sem_t full;

int count = 0;//保存缓冲区中数据数
void *produce(void*){
    while(true){
        sem_wait(&empty);//P操作,empty减少1,如果小于0,堵塞
        //临界区上锁,保证同时只能有一个生产者访问
        m.lock();
        cout << "生产了第" << ++count << "个产品!" << endl;
        m.unlock();//使用完临界区后解锁,让其他生产者使用
        sem_post(&full);//V操作,full加1,如果小于等于0,唤醒线程
    }
}

void* consume(void*){
    while(true){
        sem_wait(&full);//P操作,full减少1,如果小于0,堵塞
        m.lock(); //临界区上锁,保证同时只能有一个消费者访问
        cout << "消费了一个产品,还剩余" << --count<< "个产品" << endl;
        m.unlock();//使用完临界区后解锁,让其他消费者使用
        sem_post(&empty);//V操作,full加1,如果小于等于0,唤醒线程
    }
}

#define P_NUM 8 //生产者的数量
#define C_NUM 7 //消费者的数量
#define BUFFER_SIZE 20
int main(){
    //创建两个生产者
    pthread_t producers[P_NUM];
    //创建三个消费者
    pthread_t consumers[C_NUM];

    //初始化信号量
    int ini1 = sem_init(&empty,0,BUFFER_SIZE);
    int ini2 = sem_init(&full,0,0);
    if(ini1 != 0 && ini2 != 0){
        cout << "sem init failed!" << endl;
        return -1;
    }
    for(int i = 0;i < P_NUM;i++){
        pthread_create(&producers[i],NULL,produce,NULL);
    }
    for(int i = 0;i < C_NUM;i++){
        pthread_create(&consumers[i],NULL,consume,NULL);
    }

    for(int i = 0;i < P_NUM;i++){
        pthread_join(producers[i],NULL);
    }

        for(int i = 0;i < C_NUM;i++){
        pthread_join(consumers[i],NULL);
    }
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值