boost中的mutex与lock

来源:互联网 发布:淘宝网的交易模式分析 编辑:程序博客网 时间:2024/04/29 20:34

基本用法:

HANDLE g_mutex = NULL; void test() {     ::WaitForSingleObject(g_mutex, INFINITE);     //do something...     ReleaseMutex(g_mutex); } 
封装:

class MyMutex { public:     MyMutex()         :m_hMutex(NULL)     {     }     MyMutex(wchar_t* pMutexName)         :m_hMutex(NULL)     {         createMutex(pMutexName);     }     virtual ~MyMutex()     {        destroyMutex();     }     bool lock()     {         return m_hMutex ? (::WaitForSingleObject(m_hMutex,INFINITE) == WAIT_OBJECT_0) : false;     }     void unlock()     {         ReleaseMutex(m_hMutex);     }     bool createMutex(wchar_t* pMutexName)     {         if (m_hMutex)         {             return true;         } m_hMutex = ::CreateMutex(NULL, FALSE, pMutexName);         return m_hMutex != NULL;     }     void destroyMutex()     {         CloseHandle(m_hMutex); m_hMutex = NULL;     }     bool openMutex(wchar_t* pMutexName)     {         if (m_hMutex)         {             return true;         } m_hMutex = ::OpenMutex(SYNCHRONIZE, FALSE, pMutexName);         return m_hMutex != NULL;     } private:     HANDLE m_hMutex; }; 
用法:

void test1() {     MyMutex mutex;     mutex.createMutex(L"mutex_test_name1");     if (mutex.lock())     {         //do something...         mutex.unlock();     } } 
帮助类:

class MyMutexLockGuard { public:     MyMutexLockGuard(MyMutex* pMutex)     { m_pMutex = pMutex;         if (m_pMutex)         {             m_pMutex->lock();         }     }     virtual ~MyMutexLockGuard()     {         if (m_pMutex)         {             m_pMutex->unlock();         }     } private:     MyMutex* m_pMutex; }; 
void test2() {     MyMutex mutex(L"mutex_test_name2");     {//scope 1         MyMutexLockGuard lock(&mutex);         //do something...     }     //out of the scope 1, the mutex has been unlocked } 

当离开作用域1时,lock对象被析构,自动调用mutex.unlock函数释放锁。是不是很爽...

需要注意的是CreateMutex和OpenMutex这两个windows api,CreateMutex的第二个参数bInitialOwner最好设为false。设为true时代表创建这个mutex的线程是直接获取这个mutex,相当于创建这个mutex的过程中调用了waitforsingleobject,因此即使后来lock和unlock配对调用,最后先启动的这个线程还是没有释放这个mutex,必须手动再调用一次unlock才行。因此设为false更稳妥些。OpenMutex的第一个参数安全属性最好设为SYNCHRONIZE ,win7和vista下不要用ALL_ACCESS,有可能失败。第二参数表示进程创建出的子进程是否可以直接继承该mutex。

上面的是mutex的基本用法,更强大的是boost中对于mutex和lock的实现。

boost中的mutex貌似有6种或者更多,我用过的有3中boost::mutex、boost::shared_mutex、boost::recursive_mutex,貌似还有boost::try_mutex、boost::time_mutex,不过没用过。

boost::mutex是最基础的锁,有lock和unlock方法,可以认为是互持锁。boost::shared_mutex是共享锁,有lock、unlock方法以及shared_lock、shared_unlock方法。boost::recursive_mutex是重入锁或者称为递归锁,这个最后再说。

boost::shared_mutex可以用来实现读写锁。多线程中的一个经典问题是一写多读,即当有线程发生写操作时,所有其他线程的读操作暂停,其他时刻,允许多个线程同时读操作。使用boost::shared_mutex构造读写锁时需要使用到boost中的lock帮助类系列(作用类似上面我写的MyMutexLockGuard)。boost::shared_lock<T>和boost::unique_lock<T>,从字面上看,shared_lock是共享的,unique_lock是独占的,shared_lock<T>只允许T是shared_mutex,而unique_lock<T>对T没有限制,如果T是shared_mutex,则在执行加锁和解锁时会调用shared_lock和shared_unlock方法,否则,则执行一般的lock和unlock方法。

实现读写锁:

typedef boost::unique_lock<boost::shared_mutex> ReadLock;      typdef boost::shared_lock<boost::shared_mutex> WriteLock;      boost::shared_mutex  read_write_mutex;      void _ReadThreadFunc()      {     ReadLock read_lock(read_write_mutex);     //read data...      }      void _WriteThreadFunc()      {       WriteLock write_lock(read_write_mutex);     //write data...      } 
 使用boost::unique_lock和boost::mutex则可以实现最基本的独占时互斥
boost::unique<boost::mutex> MyLock      boost::mutex myMutex;      void func()     {          MyLock lock(myMutex);          // do something...     } 

lock_guard:

boost::mutex g_mutex; void test4() {     boost::lock_guard<boost::mutex> lock(g_mutex);     //do something... } void test3() {     boost::lock_guard<boost::mutex> lock(g_mutex);     test4();     //do something... } int _tmain(int argc, _TCHAR* argv[]) {     test3();     return 0; } 
点击打开链接





0 0