分享

跨平台C++ 锁和信号量 mutex.h

 quasiceo 2012-12-13

跨平台C++ 锁和信号量 mutex.h

(2005-05-26 11:04:43)
标签:

杂谈

分类: 计算机与 Internet

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

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多