互斥类(Cmutex)——MFC

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


FROM: http://blog.sina.com.cn/s/blog_627ebfc30100isqx.html

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值