這裏的指的環形隊列是在邏輯上,而在物理上是採用數組模擬的,這點必須理解。我這裏實現的是單生產單消費模型。
這裏用信號量實現計數器的功能。如果之前對信號量了解不多,我這裏簡單提一下,這裏的信號量是用於同步操作,達到無衝突的訪問共享的目的。建立一個信號量必須說明此信號量所代表的意義並且賦初值。除賦初值外,信號量僅能通過PV操作來訪問。
#include<iostream>
#include<unistd.h>
#include<time.h>
#include<stdlib.h>
#include<semaphore.h>
#include<vector>
#include<pthread.h>
using namespace std;
class Rqueue{
private:
vector<int>rq;
int num;
int p_step;//生產者在環形隊列中走到哪了,方便用下標訪問“隊列”(物理上是數組)
int c_step;//;//消費者在環形隊列中走到哪了,方便用下標訪問“隊列”(物理上是數組)
sem_t p_sem;//信號量
sem_t c_sem;//信號量
public:
Rqueue(int _num=1024):num(_num),rq(_num)//構造
{
p_step=0;
c_step=0;
sem_init(&p_sem,0,4);//信號量初始化
sem_init(&c_sem,0,0);//信號量初始化
}
void P(sem_t *sem)
{
sem_wait(sem);
}
void V(sem_t* sem)
{
sem_post(sem);
}
void PopData(int &data)//從環形隊列中拿數據
{
P(&c_sem);
data= rq[c_step];
c_step++;
c_step%=num;//邏輯上模擬環形
V(&p_sem);
}
void PushData(int &data)//往環形隊列中放數據
{
P(&p_sem);
rq[p_step]=data;
p_step++;
p_step%=num;
V(&c_sem);
}
~Rqueue()//析構函數
{
sem_destroy(&p_sem);
sem_destroy(&c_sem);
}
};
void *consumer(void *arg)//消費者的操作
{
Rqueue *q=(Rqueue *)arg;
while(1)
{
int data;
q->PopData(data);
cout<<"consumer data is :"<<data<<endl;
sleep(1);
}
}
void *productor(void *arg)//生產者的操作
{
Rqueue *q=(Rqueue *)arg;
while(1)
{
int data=rand()%100+1;
q->PushData(data);
cout<<"productor data is :"<<data<<endl;
}
}
int main()
{
Rqueue r(5);
pthread_t p1,p2;//線程
srand((unsigned long)time(NULL));
pthread_create(&p1,NULL,consumer,(void *)&r);
pthread_create(&p2,NULL,productor,(void *)&r);
pthread_join(p1,NULL);
pthread_join(p2,NULL);
return 0;
}