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;
}
}