CMutex CSingleLock

CMutex CSingleLock

分类: C/C++ MFC 1571人阅读 评论(3) 收藏 举报

如下为CMutex的类定义

 

[cpp:firstline[0]] view plain copy print ?
  1. class CMutex : public CSyncObject  
  2. {  
  3.     DECLARE_DYNAMIC(CMutex)  
  4. // Constructor   
  5. public:  
  6.     /* explicit */ CMutex(BOOL bInitiallyOwn = FALSE, LPCTSTR lpszName = NULL,  
  7.         LPSECURITY_ATTRIBUTES lpsaAttribute = NULL);  
  8. // Implementation   
  9. public:  
  10.     virtual ~CMutex();  
  11.     BOOL Unlock();  
  12. };  

 


 

构造函数如下

 

[cpp:firstline[0]] view plain copy print ?
  1. CMutex::CMutex(BOOL bInitiallyOwn, LPCTSTR pstrName,  
  2.     LPSECURITY_ATTRIBUTES lpsaAttribute /* = NULL */)  
  3.     : CSyncObject(pstrName)  
  4. {  
  5.     m_hObject = ::CreateMutex(lpsaAttribute, bInitiallyOwn, pstrName);  
  6.     if (m_hObject == NULL)  
  7.         AfxThrowResourceException();  
  8. }  

 

m_hObject为基类的成员变量,其实也就是Handle了,这里可以创建或者获得一个Mutex的Handle.若m_hObject == NULL(没有获得Mutex的Handle,在已存在Mutex的情况下也是能返回一个已存在的Handle的),抛出异常。具体MSDN CreateMutex.

 


 

再看看Lock函数:从基类CSyncObject继承

 

[cpp:firstline[0]] view plain copy print ?
  1. BOOL CSyncObject::Lock(DWORD dwTimeout)  
  2. {  
  3.     DWORD dwRet = ::WaitForSingleObject(m_hObject, dwTimeout);  
  4.     if (dwRet == WAIT_OBJECT_0 || dwRet == WAIT_ABANDONED)  
  5.         return TRUE;  
  6.     else  
  7.         return FALSE;  
  8. }  

 

调用WaitForSingleObject api,dwTimeout默认为INFINITE,根据WaitForSingleObject返回的结果,正常取得访问权限返回OR超时返回,返回TRUE OR FALSE

 


 

再看UnLock函数

 

[cpp:firstline[0]] view plain copy print ?
  1. BOOL CMutex::Unlock()  
  2. {  
  3.     return ::ReleaseMutex(m_hObject);  
  4. }  

 

这里是UnLock函数,简单地调用 ReleaseMutex释放拥有的Mutex对象.

 

 

 

那么Handle从哪里释放呢?

 

[cpp:firstline[0]] view plain copy print ?
  1. CSyncObject::~CSyncObject()  
  2. {  
  3.     if (m_hObject != NULL)  
  4.     {  
  5.         ::CloseHandle(m_hObject);  
  6.         m_hObject = NULL;  
  7.     }  
  8. }  

 

基类的析构函数释放了Handle,而Mutex类中的析构函数没有具体实现.

 

 

 

接下来说一个值得注意的地方:

 

注意从Mutex构造函数的初始化列表中对基类进行初始化传入的pstrName,被赋值给了m_strName,而这是一个只有在Debug版本下才有的成员变量,估计是帮助调试用的——互斥对象名在系统内核中,用一个成员变量作为拷贝可以方便查看互斥对象名,注意Release版本中无此变量.

 

[cpp:firstline[0]] view plain copy print ?
  1. CSyncObject::CSyncObject(LPCTSTR pstrName)  
  2. {  
  3.     UNUSED(pstrName);   // unused in release builds   
  4.     m_hObject = NULL;  
  5. #ifdef _DEBUG   
  6.     m_strName = pstrName;  
  7. #endif   
  8. }  

 

 

 

给一个简单的使用示例..

 

[cpp:firstline[0]] view plain copy print ?
  1. #include <iostream>   
  2. #include <afxmt.h>   
  3. using namespace std;  
  4. CMutex g_Mutex(FALSE, __T("something different"), NULL);  
  5. DWORD WINAPI ThreadFunc(LPVOID);  
  6. int main()  
  7. {     
  8.     HANDLE l_hChildThread;  
  9.     l_hChildThread = (HANDLE)::CreateThread(NULL, 0, ThreadFunc, NULL, 0, NULL);  
  10.     g_Mutex.Lock();  
  11.     cout<<"通知子线程开始工作"<<endl;  
  12.     system("pause");  
  13.     g_Mutex.Unlock();;  
  14.     WaitForSingleObject(l_hChildThread, INFINITE);  
  15.     CloseHandle(l_hChildThread);  
  16.     cout<<"子线程工作完成"<<endl;  
  17.     return 0;  
  18. }  
  19. DWORD WINAPI ThreadFunc(LPVOID)    
  20. {  
  21.     g_Mutex.Lock();  
  22.     cout<<"子线程工作中..."<<endl;  
  23.     Sleep(1000);  
  24.     g_Mutex.Unlock();  
  25.     return 0;  
  26. }  

 

 

 

之所以写这篇blog,是因为被CSingleLock弄的有点概念不清,后面明白了,CSingleLock只是进行了再一次的封装。举个例子。有点类似autoptr,弄一层封装,用于解决下面这样的问题,若函数返回点很多,这样写会让人抓狂.

 

[cpp:firstline[0]] view plain copy print ?
  1. g_Mutex.Lock();  
  2. if (false)  
  3. {  
  4.     g_Mutex.Unlock();  
  5.     return false;  
  6. }  
  7. g_Mutex.Unlock();  

 

 

 

如果用CSingleLock则是这样

 

  1. CSingleLock(&g_Mutex, TRUE);  
  2. if (false)  
  3. {  
  4.     return false;  
  5. }  

 

 

 

先看下CSingleLock的构造函数:首先进行运行时类型识别,是否CSyncObject类型,此外还将Mutex的(或者Event等等的)Handle传递给CSingleLock对象.并用m_pObject成员变量拷贝pObject指针,用以调用CMutex CEvent等等的Lock Unlock函数.若bInitialLock设置为TRUE,则省去了调用Lock这一步.构造函数中替你调用了.

 

[cpp:firstline[0]] view plain copy print ?
  1. CSingleLock::CSingleLock(CSyncObject* pObject, BOOL bInitialLock)  
  2. {  
  3.     ASSERT(pObject != NULL);  
  4.     ASSERT(pObject->IsKindOf(RUNTIME_CLASS(CSyncObject)));  
  5.     if(pObject == NULL)  
  6.         AfxThrowInvalidArgException();  
  7.           
  8.     m_pObject = pObject;  
  9.     m_hObject = pObject->m_hObject;  
  10.     m_bAcquired = FALSE;  
  11.     if (bInitialLock)  
  12.         Lock();  
  13. }  

 

 

 

如下为,CSingleLock的析构函数,调用了Unlock那么,CSingleLock局部对象l_oSingleLock超出其作用域时,将调用l_oSingleLock的析构函数释放对CMutex CEvent CSemaphore的所有权, CSingleLock不但起到了一个autoptr的作用,还通过封装的方式让CMutex CEvent的使用方式一致.

 

[cpp:firstline[0]] view plain copy print ?
  1. _AFXMT_INLINE ::CSingleLock::~CSingleLock()  
  2.     { Unlock(); }  

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值