现在的位置: 首页 > 自动控制 > 工业·编程 > 正文

MFC中的互斥类Cmutex

2013-07-27 23:50 工业·编程 ⁄ 共 2395字 ⁄ 字号 暂无评论

一、关于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、原子操作

给我留言

留言无头像?