跨平台C++ 锁和信号量 mutex.h
(2005-05-26 11:04:43)
#ifndef _MUTEX_H_
#define _MUTEX_H_
#ifdef WIN32
#include <windows.h>
#else
#include <sys/time.h>
#include <pthread.h>
#endif
#include <vector>
using namespace std;
class MMutex
{
public:
MMutex();
~MMutex();
inline void Lock()
{
#ifdef WIN32
::EnterCriticalSection(&fMutex);
#else
(void)pthread_mutex_lock(&fMutex);
#endif
};
inline void Unlock()
{
#ifdef WIN32
::LeaveCriticalSection(&fMutex);
#else
pthread_mutex_unlock(&fMutex);
#endif
};
#ifdef WIN32
inline CRITICAL_SECTION&
getMutex(){return fMutex;}
#else
inline pthread_mutex_t&
getMutex(){return fMutex;}
#endif
private:
#ifdef WIN32
CRITICAL_SECTION
fMutex;
#else
pthread_mutex_t
fMutex;
#endif
};
class MLock
{
public:
MLock(MMutex& cs) :
_cs(cs)
{
_cs.Lock();
}
~MLock()
{
_cs.Unlock();
}
private:
MMutex& _cs;
};
class MSemaphore
{
#ifdef WIN32
public:
MSemaphore()
{
h = CreateSemaphore(NULL, 0, MAXLONG, NULL);
}
void Signal()
{
ReleaseSemaphore(h, 1, NULL);
}
bool Wait()
{
return WaitForSingleObject(h, INFINITE) ==
WAIT_OBJECT_0;
}
bool Wait(unsigned int msecond)
{
return WaitForSingleObject(h, msecond) ==
WAIT_OBJECT_0;
}
~MSemaphore()
{
CloseHandle(h);
}
private:
HANDLE h;
#else
public:
MSemaphore() : count(0)
{
pthread_cond_init(&cond, NULL);
}
void Signal()
{
MLock l(cs);
count++;
pthread_cond_signal(&cond);
}
bool Wait()
{
MLock l(cs);
if(count == 0) {
pthread_cond_wait(&cond,
&cs.getMutex());
}
count--;
return true;
}
bool Wait(unsigned int msecond)
{
MLock l(cs);
if(count == 0) {
timeval timev;
timespec t;
gettimeofday(&timev, NULL);
t.tv_sec = timev.tv_sec + (msecond/1000);
t.tv_nsec = (msecond%1000)*1000*1000;
int ret =
pthread_cond_timedwait(&cond,
&cs.getMutex(), &t);
if(ret != 0) {
return false;
}
}
count--;
return true;
}
private:
pthread_cond_t cond;
MMutex cs;
int count;
#endif
public:
MSemaphore(const MSemaphore&);
MSemaphore& operator=(const
MSemaphore&);
};
template<typename T>
class MSingleton {
public:
MSingleton() { };
virtual ~MSingleton() {
};
static T* getInstance() {
return instance;
}
static void newInstance() {
if(instance)
delete instance;
instance = new T();
}
static void deleteInstance() {
if(instance)
delete instance;
instance = NULL;
}
protected:
static T* instance;
private:
MSingleton(const MSingleton&);
MSingleton& operator=(const
MSingleton&);
};
template<typename T> T*
MSingleton<T>::instance
= NULL;
template<typename Listener>
class Speaker {
typedef vector<Listener*>
ListenerList;
typedef typename
ListenerList::iterator
ListenerIter;
public:
Speaker() { };
virtual ~Speaker() { };
void fire(typename
Listener::Types type) throw()
{
MLock l(listenerCS);
ListenerList tmp = listeners;
for(ListenerIter i=tmp.begin(); i != tmp.end(); ++i)
{
(*i)->onAction(type);
}
}
template<class T>
void fire(typename
Listener::Types type, const
T& param) throw () {
MLock l(listenerCS);
ListenerList tmp = listeners;
for(ListenerIter i=tmp.begin(); i != tmp.end();
++i) {
(*i)->onAction(type,
param);
}
}
template<class T, class
T2>
void fire(typename
Listener::Types type, const
T& p, const T2& p2) throw()
{
MLock l(listenerCS);
ListenerList tmp = listeners;
for(ListenerIter i=tmp.begin(); i != tmp.end();
++i) {
(*i)->onAction(type, p,
p2);
}
}
template<class T, class T2, class
T3>
void fire(typename
Listener::Types type, const
T& p, const T2& p2, const
T3& p3) throw() {
MLock l(listenerCS);
ListenerList tmp = listeners;
for(ListenerIter i=tmp.begin(); i != tmp.end();
++i) {
(*i)->onAction(type, p, p2,
p3);
}
}
template<class T, class T2, class T3, class
T4>
void fire(typename
Listener::Types type, const
T& p, const T2& p2, const
T3& p3, const T4& p4) throw()
{
MLock l(listenerCS);
ListenerList tmp = listeners;
for(ListenerIter i=tmp.begin(); i != tmp.end();
++i) {
(*i)->onAction(type, p, p2,
p3, p4);
}
}
template<class T, class T2, class T3, class
T4, class T5>
void fire(typename
Listener::Types type, const
T& p, const T2& p2, const
T3& p3, const T4& p4, const
T5& p5) throw() {
MLock l(listenerCS);
ListenerList tmp = listeners;
for(ListenerIter i=tmp.begin(); i != tmp.end();
++i) {
(*i)->onAction(type, p, p2,
p3, p4, p5);
}
}
template<class T, class T2, class T3, class
T4, class T5, class T6>
void fire(typename
Listener::Types type, const
T& p, const T2& p2, const
T3& p3, const T4& p4, const
T5& p5, const T6& p6) throw()
{
MLock l(listenerCS);
ListenerList tmp = listeners;
for(ListenerIter i=tmp.begin(); i != tmp.end();
++i) {
(*i)->onAction(type, p, p2,
p3, p4, p5, p6);
}
}
void addListener(Listener* aListener)
{
MLock l(listenerCS);
if(find(listeners.begin(), listeners.end(), aListener)
== listeners.end())
listeners.push_back(aListener);
}
void removeListener(Listener* aListener)
{
MLock l(listenerCS);
ListenerIter i = find(listeners.begin(),
listeners.end(), aListener);
if(i != listeners.end())
listeners.erase(i);
}
void removeListeners() {
MLock l(listenerCS);
listeners.clear();
}
protected:
ListenerList listeners;
MMutex listenerCS;
};
#endif
跨平台C++ 锁和信号量 mutex.cpp
(2005-05-26 11:05:14)
#include "mutex.h"
#ifndef WIN32
static pthread_mutexattr_t *sMutexAttr=NULL;
static void MutexAttrInit();
static pthread_once_t sMutexAttrInit =
PTHREAD_ONCE_INIT;
#endif
MMutex::MMutex()
{
#ifdef WIN32
::InitializeCriticalSection(&fMutex);
#else
(void)pthread_once(&sMutexAttrInit,
MutexAttrInit);
(void)pthread_mutex_init(&fMutex,
sMutexAttr);
#endif
}
#ifndef WIN32
void MutexAttrInit()
{
sMutexAttr =
(pthread_mutexattr_t*)malloc(sizeof(pthread_mutexattr_t));
::memset(sMutexAttr, 0,
sizeof(pthread_mutexattr_t));
pthread_mutexattr_init(sMutexAttr);
}
#endif
MMutex::~MMutex()
{
#ifdef WIN32
::DeleteCriticalSection(&fMutex);
#else
pthread_mutex_destroy(&fMutex);
#endif
}