【Linux】生产消费模型实践 --- 基于信号量的环形队列
#pragma once
#include <vector>
#include <>
const int default_cap = 5;
template <class T>
class RingQueue
{
public:
RingQueue(int max_cap = default_cap) : _rq(max_cap), _max_cap(max_cap), _p_step(0), _c_step(0)
{
// 信号量初始化
sem_init(&_space_sem, 0, _max_cap);
sem_init(&_data_sem, 0, 0);
//锁进行初始化
pthread_mutex_init(&_c_mtx , nullptr);
pthread_mutex_init(&_p_mtx , nullptr);
}
// 获取信号量
void P(sem_t &sp)
{
sem_wait(&sp);
}
// 释放信号量
void V(sem_t &sp)
{
sem_post(&sp);
}
// 插入操作
void Push(const T &t)
{
// 获取空间信号量 --
P(_space_sem);
//临界区上锁
pthread_mutex_lock(&_p_mtx );
_rq[_p_step] = t;
_p_step++;
_p_step %= _max_cap;
//解锁
pthread_mutex_unlock(&_p_mtx);
// 释放信号量 ++
V(_data_sem);
}
// 获取操作
void Pop(T *t)
{
// 获取资源信号量
P(_data_sem);
pthread_mutex_lock(&_c_mtx);
*t = _rq[_c_step];
_c_step++;
_c_step %= _max_cap;
pthread_mutex_unlock(&_c_mtx);
// 释放信号量
V(_space_sem);
}
~RingQueue()
{
// 销毁对应信号量!
sem_destroy(&_space_sem);
sem_destroy(&_data_sem);
//锁进行释放
pthread_mutex_destroy(&_c_mtx);
pthread_mutex_destroy(&_p_mtx);
}
private:
// 底层线性结构,模拟环形队列
std::vector<T> _rq;
// 最大容量
int _max_cap;
// 生产者/消费者 下标
int _p_step;
int _c_step;
// 空间/资源 信号量
sem_t _space_sem;
sem_t _data_sem;
// 生产 / 消费 锁
pthread_mutex_t _p_mtx;
pthread_mutex_t _c_mtx;
};