###############封装锁#################
#ifndef _PTHREAD_MUTEX_H_
#define _PTHREAD_MUTEX_H_
#define _PTHREAD_MUTEX_H_
#include <pthread.h>
#include <stdlib.h>
#include <unistd.h>
#include <stdlib.h>
#include <unistd.h>
class CPthread_Mutex
{
public:
CPthread_Mutex();
~CPthread_Mutex();
bool Enter();
bool Leave();
private:
pthread_mutex_t m_mutex;
};
};
#endif
#include "../include/Pthread_Mutex.h"
CPthread_Mutex::CPthread_Mutex()
{
pthread_mutex_init(&m_mutex, NULL);
}
{
pthread_mutex_init(&m_mutex, NULL);
}
CPthread_Mutex::~CPthread_Mutex()
{
pthread_mutex_destroy(&m_mutex);
}
{
pthread_mutex_destroy(&m_mutex);
}
bool CPthread_Mutex::Enter()
{
pthread_mutex_lock(&m_mutex);
}
{
pthread_mutex_lock(&m_mutex);
}
bool CPthread_Mutex::Leave()
{
pthread_mutex_unlock(&m_mutex);
}
{
pthread_mutex_unlock(&m_mutex);
}
#ifndef _GUARD_H_
#define _GUARD_H_
#define _GUARD_H_
#include "Pthread_Mutex.h"
class CGuard
{
public:
{
public:
inline CGuard(CPthread_Mutex& mutex):m_mutex(mutex)
{
m_mutex.Enter();
};
inline ~CGuard()
{
m_mutex.Leave();
};
{
m_mutex.Enter();
};
inline ~CGuard()
{
m_mutex.Leave();
};
private:
CPthread_Mutex m_mutex;
};
};
#endif
############消息队列模板#############
#ifndef _MSG_QUE_3_H_
#define _MSG_QUE_3_H_
#define _MSG_QUE_3_H_
#include "Guard.h"
#include "Semaphore.h"
#include <assert.h>
#include <list>
#include "Semaphore.h"
#include <assert.h>
#include <list>
/// \class TMsgQue
/// \brief 线程安全的优先级消息队列模板类,能实例化成接受各种数据类型消息的消息队列类。
///
/// 示例代码如下:
/// \code
/// struct NetMessage;
/// struct GUIMessage;
///
/// TMsgQue<NetMessage> myNetMsgQue;
/// TMsgQue<GUIMessage> myGUIMsgQue;
///
/// NetMessage msg;
/// makeNetMessage(&msg);
/// myNetMsgQue.SendMessage(msg);
/// \endcode
template<typename M>
class TMsgQue
{
public:
/// \brief 线程安全的优先级消息队列模板类,能实例化成接受各种数据类型消息的消息队列类。
///
/// 示例代码如下:
/// \code
/// struct NetMessage;
/// struct GUIMessage;
///
/// TMsgQue<NetMessage> myNetMsgQue;
/// TMsgQue<GUIMessage> myGUIMsgQue;
///
/// NetMessage msg;
/// makeNetMessage(&msg);
/// myNetMsgQue.SendMessage(msg);
/// \endcode
template<typename M>
class TMsgQue
{
public:
/// 构造函数
/// \param queueSize 消息队列的长度
/// \param prioLevels 优先级等级数,等级数越少,消息处理速度越快
TMsgQue(int queueSize = 1024, int prioLevels = 1)
{
m_queueSize = queueSize;
m_prioLevels = prioLevels;
m_prioIterator = new Iterator[prioLevels];
for (int i = 0; i < prioLevels; i++)
{
m_prioIterator[i] = m_queue.begin();
}
};
/// \param queueSize 消息队列的长度
/// \param prioLevels 优先级等级数,等级数越少,消息处理速度越快
TMsgQue(int queueSize = 1024, int prioLevels = 1)
{
m_queueSize = queueSize;
m_prioLevels = prioLevels;
m_prioIterator = new Iterator[prioLevels];
for (int i = 0; i < prioLevels; i++)
{
m_prioIterator[i] = m_queue.begin();
}
};
/// 析构函数
virtual ~TMsgQue()
{
delete []m_prioIterator;
};
virtual ~TMsgQue()
{
delete []m_prioIterator;
};
/// 发送消息
/// \param message 消息对象指针
/// \param priority 发送的优先级,只能在0到prioLevels-1之间
/// \return 发送结果,如果消息队列已满,或者优先级不对,调用失败
bool sendMessage (M& message, int priority = 0)
{
Iterator oldIterator, newIterator;
if(priority < 0 || priority >= m_prioLevels)
{
return false;
}
/// \param message 消息对象指针
/// \param priority 发送的优先级,只能在0到prioLevels-1之间
/// \return 发送结果,如果消息队列已满,或者优先级不对,调用失败
bool sendMessage (M& message, int priority = 0)
{
Iterator oldIterator, newIterator;
if(priority < 0 || priority >= m_prioLevels)
{
return false;
}
m_mutex.Enter();
if(m_queue.size() >= (size_t)m_queueSize)
{
m_mutex.Leave();
return false;
}
if(m_queue.size() >= (size_t)m_queueSize)
{
m_mutex.Leave();
return false;
}
oldIterator = m_prioIterator[priority];
newIterator = m_queue.insert(oldIterator, message);
newIterator = m_queue.insert(oldIterator, message);
for(int i = priority + 1; i < m_prioLevels; i++)
{
if(m_prioIterator[i] == oldIterator)
{
m_prioIterator[i] = newIterator;
}
else
{
break;
}
}
m_mutex.Leave();
{
if(m_prioIterator[i] == oldIterator)
{
m_prioIterator[i] = newIterator;
}
else
{
break;
}
}
m_mutex.Leave();
m_semaphore.Post();
return true;
};
return true;
};
/// 接收消息
/// \param message 消息对象指针
/// \param wait 在消息队列为空的情况下是否阻塞
/// \param deque 接受消息后是否让消息出列
/// \return 接收结果,如果消息队列为空,又是非阻塞模式,则返回失败
bool recvMessage (M& message, bool wait = true, bool deque = true)
{
if(wait)
{
m_semaphore.Pend();
assert(m_queue.size());
}
/// \param message 消息对象指针
/// \param wait 在消息队列为空的情况下是否阻塞
/// \param deque 接受消息后是否让消息出列
/// \return 接收结果,如果消息队列为空,又是非阻塞模式,则返回失败
bool recvMessage (M& message, bool wait = true, bool deque = true)
{
if(wait)
{
m_semaphore.Pend();
assert(m_queue.size());
}
if(!wait)
{
if (m_queue.empty())
{
return false;
}
m_semaphore.Pend();
}
CGuard guard(m_mutex);
{
if (m_queue.empty())
{
return false;
}
m_semaphore.Pend();
}
CGuard guard(m_mutex);
message = m_queue.front();
if(deque)
{
for(int i = m_prioLevels - 1; i >= 0; i--)
{
if(m_prioIterator[i] == m_queue.begin())
{
m_prioIterator[i]++;
}
else
{
break;
}
}
m_queue.pop_front();
}
else
{
m_semaphore.Post();
}
{
for(int i = m_prioLevels - 1; i >= 0; i--)
{
if(m_prioIterator[i] == m_queue.begin())
{
m_prioIterator[i]++;
}
else
{
break;
}
}
m_queue.pop_front();
}
else
{
m_semaphore.Post();
}
return true;
}
}
void clean()
{
CGuard guard(m_mutex);
{
CGuard guard(m_mutex);
int n = m_queue.size();
for(int i = 0; i < n; i++)
{
m_semaphore.Pend();
m_queue.pop_back();
}
}
for(int i = 0; i < n; i++)
{
m_semaphore.Pend();
m_queue.pop_back();
}
}
/// 得到消息队列中消息个数
int size()
{
CGuard guard(m_mutex);
int size()
{
CGuard guard(m_mutex);
return m_queue.size();
}
}
/// 得到消息队列的最大长度
int getMaxSize()
{
CGuard guard(m_mutex);
int getMaxSize()
{
CGuard guard(m_mutex);
return m_queueSize;
}
}
/// 得到消息队列的最大长度,将在下次SendMessage时生效
/// \param size 新的消息队列长度,可以比原来的大或者小
void setMaxSize(int size)
{
CGuard guard(m_mutex);
/// \param size 新的消息队列长度,可以比原来的大或者小
void setMaxSize(int size)
{
CGuard guard(m_mutex);
m_queueSize = size;
}
private:
typedef std::list<M> Queue;
typedef typename Queue::iterator Iterator;
}
private:
typedef std::list<M> Queue;
typedef typename Queue::iterator Iterator;
Queue m_queue;
Iterator* m_prioIterator;
CPthread_Mutex m_mutex;
CSemaphore m_semaphore;
int m_queueSize;
int m_prioLevels;
};
Iterator* m_prioIterator;
CPthread_Mutex m_mutex;
CSemaphore m_semaphore;
int m_queueSize;
int m_prioLevels;
};
#endif//_MSG_QUE_3_H_