一、关于CMutex类
1、CMutex只是对 win32API 的互斥操作进行了封装
2、它的参数与 win32 API 中的 CreatMutex() 相对应
3、CMutex的构造函数调用 CreatMutex() 创建并检查
4、其Lock操作从基类继承,调用WaitForSingleObject()获得所有权,互斥类重载 Unlock 调用ReleaseMutex()释放所有权。
所以,MFC其实就是简单了封装了 win32 API 函数。
二、CMutex的实现:
1、CMutex::CMutex(BOOL bInitiallyOwn, LPCTSTR pstrMame)
2、CMutex::~CMutex()
3、BOOL CMutex::Unlock()
三、使用,用法:
首先,创建工程——win32 console Application——工程名——OK——an application that supports MFC——finish
1、例子1,单独操作(伪代码)
CMutex mutex; //声明互斥
UINT mythreadA:mutex.Lock();
//动作
mutex.Unlock();
Sleep(1000);
UINT mythreadB:mutex.Lock();
//动作
mutex.Unlock();
Sleep(1000);
int _tmain():int flag=0;
if(!AfxWinInit(::GetModuleHandle(NULL),NULL,::GetCommandLine(),0))
{cerr<<.......... ; flag=1; }
else
{
AfxBeginThread(mythreadA,NULL);
AfxBeginThread(mythreadB,NULL);
Sleep(10000);
}
return flag;
2、这个例子(和CSingleLock使用):
1)通过某个成员函数访问被 CMutex 对象保护的资源(即array[1024];)时,要创建CSingleLock或者是CMultiLock,它以 CMutex 对象的指针为参数。
2)然后调用 CSingleLock或CMultiLock的成员函数Lock()和Unlock()来获取和释放资源
3)这样,在一个进程使用该类时,就不必担心同步问题了。
#include"afxmt.h"//同步操作时需要包含的头文件
#include<iostream.h>
class CResourse //定义资源类
{
private:
int array[1024];
CMutex mutex; //此时互斥量受到保护
public:
CResourse();//构造函数
~CResourse();//析构函数
void setdata(int n ,int data);
int getdata(int n);
}
//以下为资源类内的公共函数初始化
CResourse::CResourse:mutex(FALSE,NULL)
{ for(int i=0;i<1024;i++) array[i]=0; }
CResourse::~CResourse() {}
void CResourse::setdata(int n, int data)
{
CSingleLock sLock(&mutex);
sLock.Lock();
if(sLock.IsLocked())
array[n]=data;
sLock.Unlock();
}
int CResourse::getdata(int n)
{
int t;
CSingleLock sLock(&mutex);
sLock.Lock();
if(sLock.IsLocked())
t=array[n];
sLock.Unlock();
return t;
}
UINT mythread1(LPVOID pParam);
UINT mythread2(LPVOID pParam);
CResourse res; //声明全局变量
UINT mythread1(LPVOID pParam);
{ res.setdata(1,100); retuen 1; }
UINT mythread2(LPVOID pParam);
{ cout<<res.getdata(1)<<endl; retuen 1; }
int main(int argc, TCHAR* argv[], TCHAR* envp[] )
{
AfxBeginThread(mythread1,NULL);
AfxBeginThread(mythread2,NULL);
Sleep(1000);
return 1;
}
四、小结
上面两个例子的区别主要是:
1、一个是CMutex的单独使用,一个是CMutex和CSingleLock一起使用。
2、第一个是关于同步的问题;
3、第二个是关于资源类受到保护的问题。受到保护时,需要用CSingleLock或CMultiLock 间接访问。
五、关于Unlock()
在CSingleLock中,我们已经知道了它有 有参数 和 无参数 两种。
1、问题是:
在使用有参数的时,可能会造成互斥量的所有权不能得到释放;而使用无参数的时,却能正确释放。
2、原因是:
1)CSingleLock的解锁函数在实现中,首先检查同步对象的指针是否有效,若有效,则检查互斥量是否被线程占有,若有,则进一步调用CSingleLock的Unlock.
2)有参数的只用于CSingleLock对象和信号量 相联系的时候。
3)当CSingleLock与互斥量相联系时,调用有参数的只是返回真值,这导致互斥量一直处于被锁定的状态。
于是,其他线程函数调用解锁函数时,由于互斥量被锁定,就不再调用相应同步类的无参数解锁函数了。
然后当 CSingleLock析构的时候,Unlock 也发生同上的操作。
于是使得互斥量得不到释放。
六、关于互斥量的进一步分析内容
1、线程间通信
2、状态转换
3、快照
4、原子操作