linux编程:通过信号量实现生产者与消费者模型

linux编程:通过信号量实现生产者与消费者模型

信号量: 用于实现同步与互斥。

本质: 就是一个计数器,对资源进行计数以及提供一个pcb等待队列,向外提供P/V操作接口,实现同步与互斥

P操作: 在临界资源访问之前进行P操作,计数-1,对计数进行判断,小于0则不符合访问条件,使线程阻塞或报错返回,否则正确返回获取资源

V操作: 在生产资源之后,进行V操作,计数+1,唤醒一个等待的线程或进程

互斥的实现:
计数为1,表示资源只有一个,在资源访问之前P操作–加锁,其他线程则无法访问(这时候表示已经没有资源了),访问完毕之后进行V操作–解锁流程:

  1. 创建信号量;
  2. 初始化信号量;
  3. 在获取资源之前P操作;
  4. 生产资源之后V操作;
  5. 销毁信号量
#include<vector>
#include<pthread.h>
#include<semaphore.h>
#include<cstdio>

#define MAX_QUEUE 5

class RingQueue{
    private:
        std::vector<int>_queue;
        int _read_step;
        int _write_step;
        int _capacity;
        sem_t _sem_lock;//用于实现锁
        sem_t _sem_idle;//用于统计空闲空间数
        sem_t _sem_data;//用于统计数据空间
    public:
        RingQueue(int cap = MAX_QUEUE):_queue(cap),_capacity(cap),_read_step(0),_write_step(0){
            sem_init(&_sem_lock,0,1);//用于实现锁则计数为1
            sem_init(&_sem_idle,0,cap);//空闲空间初始为5
            sem_init(&_sem_data,0,0);//数据初值为0
        }
        ~RingQueue(){
            sem_destroy(&_sem_lock);
            sem_destroy(&_sem_idle);
            sem_destroy(&_sem_data);
        }
        bool Push(int data){
            sem_wait(&_sem_idle);//判断是否有空闲空间,空闲空间计数-1
            sem_wait(&_sem_lock);//P操作加锁
            _queue[_write_step]=data;
            _write_step=(_write_step+1)%_capacity;
            sem_post(&_sem_lock);//V操作解锁
            sem_post(&_sem_data);//数据空间计数+1
            return true;
        }

        bool Pop(int *data){
            sem_wait(&_sem_data);//判断是否有数据空间,数据空间计数-1
            sem_wait(&_sem_lock);//P操作加锁
            *data=_queue[_read_step];
            _read_step=(_read_step+1)%_capacity;
            sem_post(&_sem_lock);//V操作解锁
            sem_post(&_sem_idle);//空闲空间计数+1
            return true;
        }
};


void *thr_cus(void *arg){
    RingQueue *queue = (RingQueue*)arg;
    while(1){
        int data;
        queue->Pop(&data);
        printf("get data:%d --\n",data);
    }
    return NULL;
}

void *thr_pro(void *arg){
    RingQueue *queue = (RingQueue*)arg;
    int data= 0;
    while(1){
        queue->Push(data);
        printf("get data:%d ++\n",data++);
    }
    return NULL;
}


int main()
{
    int ret,i;
    RingQueue queue;
    pthread_t ctid[4],ptid[4];
    for(i=0;i<4;i++){
        ret=pthread_create(&ctid[i],NULL,thr_cus,(void*)&queue);
        if(ret!=0){
            printf("craete theread error\n");
            return -1;
        }
    }
    for(i=0;i<4;i++){
        ret=pthread_create(&ptid[i],NULL,thr_pro,(void*)&queue);
         if(ret!=0){
            printf("craete theread error\n");
             return -1;
         }
    }
    for(i=0;i<4;i++){
         pthread_join(ctid[i],NULL);
         pthread_join(ptid[i],NULL);
     }
}

运行结果
在这里插入图片描述

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值