boost中的mutex与lock

基本用法:

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
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值