目录
1.信号量的概念
信号量就是一个计数器,可以进行PV操作,P操作原则性++,V操作原子性--;
1.1.信号量证明保证同步的
2.信号量的接口
3.环形队列
4.使用环形队列+信号量实现生产消费模型
ring_buffer.hpp
#pragma once
#include<iostream>
#include<vector>
#include<pthread.h>
#include<semaphore.h>
#define RB_CAPACITY 10
namespace ns_ring_buffer{
template<class T>
class RingBuffer
{
private:
std::vector<T> _v;
sem_t blank;
sem_t data;
pthread_mutex_t mtx;
int _cap;
//分别的下标记录位置
int _p_index;
int _c_index;
public:
RingBuffer(const T& cap=RB_CAPACITY)
:_cap(cap)
,_v(cap)
{
_p_index=_c_index=0;
//初始化
sem_init(&blank,0,RB_CAPACITY);
sem_init(&data,0,0);
pthread_mutex_init(&mtx,nullptr);
}
~RingBuffer()
{
sem_destroy(&blank);
sem_destroy(&data);
pthread_mutex_destroy(&mtx);
}
void Push(const T& in)
{
sem_wait(&blank);//--空位置
//多线程保护临界资源
pthread_mutex_lock(&mtx);
_v[_p_index]=in;
_p_index++;
_p_index%=_cap;
pthread_mutex_unlock(&mtx);
sem_post(&data);//++数据
}
void Pop(T* out)
{
sem_wait(&data);//--数据
//多线程保护临界资源
pthread_mutex_lock(&mtx);
*out=_v[_c_index];
_c_index++;
_c_index%=_cap;
pthread_mutex_unlock(&mtx);
sem_post(&blank);//++空位置
}
};
}
mysemaphore.cc
#include "ring_buffer.hpp"
#include<cstdlib>
#include<unistd.h>
#include<time.h>
using namespace ns_ring_buffer;
void* Consumer(void* args)
{
RingBuffer<int>* rb=(RingBuffer<int>*)args;
while(true){
int data=0;
rb->Pop(&data);
std::cout<<"消费数据:"<<data<<std::endl;
//sleep(1);
}
}
void* Producer(void* args)
{
RingBuffer<int>* rb=(RingBuffer<int>*)args;
while(true){
int data=rand()%20+1;
std::cout<<"生产数据:"<<data<<std::endl;
rb->Push(data);
sleep(1);
}
}
int main()
{
srand((long long)time(nullptr));
//创建两个或者多个轻量级进程和一个环形数组
pthread_t c,p;
RingBuffer<int>* rb=new RingBuffer<int>;
pthread_create(&c,nullptr,Consumer,(void*)rb);
pthread_create(&p,nullptr,Producer,(void*)rb);
pthread_join(c,nullptr);
pthread_join(p,nullptr);
return 0;
}
执行结果: