互斥体是CMutex类的对象,也只允许一个线程占有某个共享资源,以保护独占式共享资源。因此,互斥体的使用方法与临界段的使用方法极为相似,所不同的是临界段只能在同一个进程中对线程进行同步,而互斥体可以用在不同的进程中进行线程同步控制。
CMutex类的构造函数原型为:
CMutex(
BOOL bInitiallyOwn /* = FALSE */, //用来指定互斥体对象初始状态是锁定(TRUE)还是非锁定(FALSE)
LPCTSTR lpszName /* = NULL */, //用来指定互斥体的名称
LPSECURITY_ATTRIBUTES lpsaAttribute /* = NULL */ //为一个指向SECURITY_ATTRIBUTES结构的指针
)
BOOL bInitiallyOwn /* = FALSE */, //用来指定互斥体对象初始状态是锁定(TRUE)还是非锁定(FALSE)
LPCTSTR lpszName /* = NULL */, //用来指定互斥体的名称
LPSECURITY_ATTRIBUTES lpsaAttribute /* = NULL */ //为一个指向SECURITY_ATTRIBUTES结构的指针
)
该对象的使用方法与临界段对象的使用方法相似,在线程中获得互斥体对象可以调用成员函数Lock(),需要交出互斥体对象时,调用成员函数UnLock()。
示例:编写一个应用程序,实现进程间线程的同步。
1.创建单文档应用程序;
2.在视图类的实现文件定义一个互斥体对象:
CMutex mutexObj(FALSE,_T(
"mutex1"));
3.在视图类的实现文件中定义线程函数:
UINT MessageThread1(LPVOID pParam)
{
mutexObj.Lock();
LPTSTR pMessage = _T( "Thread1 is started");
CWnd *pMainWnd = AfxGetMainWnd();
::MessageBox(pMainWnd->m_hWnd, pMessage, _T( "Thread message"), MB_OK);
mutexObj.Unlock();
return 0;
}
{
mutexObj.Lock();
LPTSTR pMessage = _T( "Thread1 is started");
CWnd *pMainWnd = AfxGetMainWnd();
::MessageBox(pMainWnd->m_hWnd, pMessage, _T( "Thread message"), MB_OK);
mutexObj.Unlock();
return 0;
}
4.在视图类的鼠标左键消息函数里面添加如下:
void CThreadTestView::OnLButtonDown(UINT nFlags, CPoint point)
{
AfxBeginThread(MessageThread1, _T( "Thread is started"));
CView::OnLButtonDown(nFlags, point);
}
{
AfxBeginThread(MessageThread1, _T( "Thread is started"));
CView::OnLButtonDown(nFlags, point);
}
启动程序的两个实例(运行两个此程序),单击第一个实例的窗口,即启动线程并在线程中锁定互斥体,因此在用鼠标单击第二个实例的窗口时,会没有任何反应,因为第二个实例的线程没有得到互斥体。
程序运行结果如图:
参考资料:
1.互斥类(Cmutex)——MFC http://blog.sina.com.cn/s/blog_627ebfc30100isqx.html
2.《MFC Windows应用程序设计(第2版)》