Linux環形隊列簡單實現

這裏的指的環形隊列是在邏輯上,而在物理上是採用數組模擬的,這點必須理解。我這裏實現的是單生產單消費模型。
這裏用信號量實現計數器的功能。如果之前對信號量了解不多,我這裏簡單提一下,這裏的信號量是用於同步操作,達到無衝突的訪問共享的目的。建立一個信號量必須說明此信號量所代表的意義並且賦初值。除賦初值外,信號量僅能通過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;
}

在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章