临界段类(CCriticalSection)——MFC

临界段类(CCriticalSection)——MFC

(2010-05-30 12:09:51)

一、具体实现:

_AFXMT_INLINE CCriticalSection::CCriticalSection()

_AFXMT_INLINE CCriticalSection::operator CRITICAL_SECTION*()

_AFXMT_INLINE CCriticalSection::~CCriticalSection()

_AFXMT_INLINE BOOL CCriticalSection::Lock()

_AFXMT_INLINE BOOL CCriticalSection::Lock(DWORD )

_AFXMT_INLINE BOOL CCriticalSection::Unlock()

 

二、与互斥量比较

1、和CMutex类相似,也分两种情况:单独使用,和CSingleLock使用。

2、它们能用在单个进程内的线程间同步,但互斥量除此之外还可以在多个进程间的线程同步。

3、从性能上讲,临界段要优于互斥量。

 

三、例子

1、单独使用(伪代码)

CCriticalSection section;//声明临界段

int arr[10];  //共享变量

Thread A: section.Lock();

          //访问,操作共享变量

          section.Unlock();

Thread B: section.Lock();

          //访问,操作共享变量

          section.Unlock();

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)通过某个成员函数访问被 CCriticalSection 对象保护的资源(即array[1024];)时,要创建CSingleLock或者是CMultiLock,它以 CCriticalSection 对象的指针为参数。

  2)然后调用 CSingleLock或CMultiLock的成员函数Lock()和Unlock()来获取和释放资源

  3)这样,在一个进程使用该类时,就不必担心同步问题了。

#include"afxmt.h"//同步操作时需要包含的头文件
#include<iostream.h>
class CResourse  //定义资源类

{

  private:

     int array[1024];

     CCriticalSection section;  //此时临界段受到保护

  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(&section);//以临界段为参数

   sLock.Lock();

   if(sLock.IsLocked())
      array[n]=data;
   sLock.Unlock();

}

int CResourse::getdata(int n)

{
  int t;
  CSingleLock sLock(&section);//以临界段为参数

    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;
}

以上这个例子,也是和互斥类的和CSingleLock配合使用的例子一模一样。

 

3、关于银行中客户获取ID的问题,也可以用 MFC 临界段来实现

#include"afxmt.h"//同步操作时需要包含的头文件
#include<iostream.h>
class Identifier  //定义资源类

{

  private:

     unsigned int m_id;;

     CCriticalSection section;  //此时临界段受到保护

  public:

    unsigned int getID();

}

//以下为资源类内的公共函数初始化

unsigned int Identifier::getID()

{
  unsigned int id;
  CSingleLock sLock(&section);
  sLock.Lock();
  id = m_id;
  m_id++;
  sLock.Unlock();
  return id;
}

Identifier globalID;  //声明全局变量

unsigned long _stdcall  mythread(LPVOID pParam);
{ int id = globalID.getID();  cout<<id<<"";   retuen 1;  }


int main(int argc, TCHAR* argv[], TCHAR* envp[] )
{
 HANDLE handle;
 DWORD dw;
 for(int i=0;i<100;i++)
 {
  handle = CreateThread(NULL,0,mythread,NULL,0,&dw);
  CloseHandle(handle);
 }

 Sleep(6000);
 return 0;
}

四、小结

  上面两个例子的区别主要是:

    1、一个是CCriticalSection的单独使用,二个是CCriticalSection和CSingleLock一起使用,三是根据情况使用并更新临界段内的资源。

    2、例子1是关于同步的问题;

    3、例子2 是关于资源类受到保护的问题。受到保护时,需要用CSingleLock或CMultiLock 间接访问。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值