基本用法:
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
typedef boost::unique_lock ReadLock;
typdef boost::shared_lock 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 MyLock
boost::mutex myMutex;
void func()
{
MyLock lock(myMutex);
// do something...
}
boost::mutex g_mutex;
void test4()
{
boost::lock_guard lock(g_mutex);
//do something...
}
void test3()
{
boost::lock_guard lock(g_mutex);
test4();
//do something...
}
int _tmain(int argc, _TCHAR* argv[])
{
test3();
return 0;
}
点击打开链接