Ringqueue.hpp
#include<iostream>
#include<vector>
#include<semaphore.h>
static const int N=5;
template<class T>
class ringqueue
{
private:
void P(sem_t &s)
{
sem_wait(&s);
}
void V(sem_t&s)
{
sem_post(&s);
}
public:
ringqueue(int num=N)
: _ring(num),_cap(num)
{
sem_init(&_data_sem,0,0);
sem_init(&_space_sem,0,num);
_c_step=_p_step=0;
}
~ringqueue()
{
sem_destroy(&_data_sem);
sem_destroy(&_space_sem);
}
void push(const T&in)
{
P(_space_sem);
_ring[_p_step++]=in;
_p_step%=_cap;
V(_data_sem);
}
void pop(T*out)
{
P(_data_sem);
*out=_ring[_c_step++];
_c_step%=_cap;
V(_space_sem);
}
private:
int _c_step;
int _p_step;
std::vector<int> _ring;
int _cap;
sem_t _data_sem;
sem_t _space_sem;
};
makefile
ringqueue:main.cc
g++ -o $@ $^ -std=c++11 -lpthread
.PHONY:clean
clean:
rm -f ringqueue
main.cc
#include"Ringqueue.hpp"
#include<pthread.h>
#include<unistd.h>
using namespace std;
void*consumerRoutine(void*args)
{
ringqueue<int>*rq=(ringqueue<int>*)args;
while(true)
{
int data=0;
rq->pop(&data);
cout<<"consumer done:"<<data<<endl;
sleep(1);
}
}
void*productorRoutine(void*args)
{
ringqueue<int>*rq=(ringqueue<int>*)args;
while(true)
{
int data=1;
rq->push(data);
cout<<"productor done:"<<data<<endl;
}
}
int main()
{
ringqueue<int>*rq=new ringqueue<int>();
pthread_t c;
pthread_t p;
pthread_create(&c,nullptr,consumerRoutine,rq);
pthread_create(&p,nullptr,productorRoutine,rq);
pthread_join(c,nullptr);
pthread_join(p,nullptr);
return 0;
}