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

MFC中的临界段类CCriticalSection

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

一、具体实现:

_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 间接访问。

给我留言

留言无头像?