环形消息队列的实现

struct MessageQueue
{
 int* m_pArray;

 //消息队列长度
 int m_iLength;

 //消息队列的读下标
 int m_iRead;

 //消息队列的写下标
 int m_iWrite;

 //多个写操作时的互斥锁
 pthread_mutex_t m_mutex;

 //该消息队列的条件变量
 pthread_cond_t m_cond;
};

MessageQueue* ip_create_messagequeue(int length)
{
 MessageQueue* pMessageQueue = (MessageQueue*)malloc(sizeof(MessageQueue));

 if (NULL == pMessageQueue)
 {
  #ifdef _LOG
   printf("%s : %d get memory is NULL", __FILE__, __LINE__);
  #else
   WRITELOG(ErrLog, "%s : %d get memory is NULL", __FILE__, __LINE__);
  #endif
 
  return NULL;
 }
 else
 {
  //增加一个长度
  length++;
 
  pMessageQueue ->m_pArray = (int*)malloc(sizeof(int) * length);

  if (NULL == pMessageQueue ->m_pArray)
  {
   #ifdef _LOG
    printf("%s : %d get memory is NULL", __FILE__, __LINE__);
   #else
    WRITELOG(ErrLog, "%s : %d get memory is NULL", __FILE__, __LINE__);
   #endif
  
   free(pMessageQueue);

   return NULL;
  }
  else
  {
   memset(pMessageQueue ->m_pArray, 0, length * sizeof(int));

   pMessageQueue ->m_iLength = length;
   pMessageQueue ->m_iRead = pMessageQueue ->m_iWrite = 0;

   //初始化互斥锁
   pthread_mutex_init(&(pMessageQueue ->m_mutex), NULL);

   pthread_cond_init(&(pMessageQueue ->m_cond), NULL);

   return pMessageQueue;
  }
 }
}

//增加一个
bool ip_in_messagequeue(MessageQueue* pMessageQueue, int value)
{
 assert(NULL != pMessageQueue);
 
 int saveRead = pMessageQueue ->m_iRead;

 //写下标在读下标之前
 if (pMessageQueue ->m_iWrite >= saveRead)
 {
  //写下标在读下标前面已满的情况只有读下标在原地
  //或者写下标在末尾,读下标前进了一位
  //消息队列已满
  if ((pMessageQueue ->m_iWrite - pMessageQueue ->m_iRead) == pMessageQueue ->m_iLength - 2)
  {
   return false;
  }
 
  
  /*if ((pMessageQueue ->m_iWrite + 1 == pMessageQueue ->m_iLength - 1)
  && (pMessageQueue ->m_iRead == 0))
  {
   return false;
  }

  if ((pMessageQueue ->m_iWrite == pMessageQueue ->m_iLength -1)
  && (pMessageQueue ->m_iRead == 1))
  {
   return false;
  }*/
 }
 //写下标在读下标之后
 else
 {
  //写下标和读下标之间的距离间隔1, 表示队列已满
  if (saveRead -pMessageQueue ->m_iWrite == 1)
  {
   return false;
  }
 }

 //写入消息
 (pMessageQueue ->m_pArray)[pMessageQueue ->m_iWrite] = value;

 //已经写到数组末尾
 if (pMessageQueue ->m_iWrite == pMessageQueue ->m_iLength - 1)
 {
  pMessageQueue ->m_iWrite = 0;
 }
 else
 {
  //写下标前进一位
  ++(pMessageQueue ->m_iWrite);
 }

 return true;
}

 

//当写下标和读下标重合,表示没有数据可读,写下标不可能追上读下标,
//读下标可以和写下标重合
int ip_get_messagequeue(MessageQueue* pMessageQueue)
{
 assert(NULL != pMessageQueue);

 int saveWrite = pMessageQueue ->m_iWrite;

 
 //无数据可读
 if (saveWrite == pMessageQueue ->m_iRead)
 {
  return -1;
 }
 //写下标在读下标的前面
 else if (saveWrite > pMessageQueue ->m_iRead)
 {
  int iResult = (pMessageQueue ->m_pArray)[pMessageQueue ->m_iRead];
 
  ++(pMessageQueue ->m_iRead); 
 
  return iResult;
 }
 //写下标在读下标的后面
 else
 {
  int iResult = 0;
 
  //刚好读到数组尾
  if (pMessageQueue ->m_iRead == pMessageQueue ->m_iLength - 1)
  {
   iResult = (pMessageQueue ->m_pArray)[pMessageQueue ->m_iLength - 1];

   pMessageQueue ->m_iRead = 0;

   return iResult;
  }

  iResult = (pMessageQueue ->m_pArray)[pMessageQueue ->m_iRead];

  ++(pMessageQueue ->m_iRead); 
 
  return iResult;
 }
}


void ip_addlock_messagequeue(MessageQueue* pMessageQueue)
{
 assert(NULL != pMessageQueue);

 pthread_mutex_lock(&(pMessageQueue ->m_mutex));
}


void ip_unlock_messagequeue(MessageQueue* pMessageQueue)
{
 assert(NULL != pMessageQueue);

 pthread_mutex_unlock(&(pMessageQueue ->m_mutex));
}

void ip_signal_messagequeue(MessageQueue* pMessageQueue)
{
 assert(NULL != pMessageQueue);

 pthread_cond_signal(&(pMessageQueue ->m_cond));
}

void ip_wait_messagequeue(MessageQueue* pMessageQueue)
{
 assert(NULL != pMessageQueue);

 timespec mytime;
 mytime.tv_sec = time(NULL)+1;  //Wait for 1 second, Must 
 mytime.tv_nsec = 0;
 
 pthread_cond_timedwait(&(pMessageQueue ->m_cond), &(pMessageQueue ->m_mutex), (const struct timespec *)&mytime);
}

bool ip_isempty_messagequeue(MessageQueue* pMessageQueue)
{
 assert(NULL != pMessageQueue);

 if (pMessageQueue ->m_iWrite == pMessageQueue ->m_iRead)
 {
  return true;
 }
 else
 {
  return false;
 }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值