线程同步:临界区的使用

来源:互联网 发布:淘宝发货地址怎么修改 编辑:程序博客网 时间:2024/05/16 14:26

<1>win32中临界区的使用

(1)win32中头文件

< Windows.h>

(2)临界区相关函数

void InitializeCriticalSection(LPCRITICAL_SECTION lpCriticalSection) // 初始化临界区

void EnterCriticalSection(LPCRITICAL_SECTION lpCriticalSection)      // 进入临界区

void LeaveCriticalSection(LPCRITICAL_SECTION lpCriticalSection)      // 离开临界区

void DeleteCriticalSection(LPCRITICAL_SECTION lpCriticalSection)     // 释放临界区资源

 lpCriticalSection为临界资源对象指针。

(3)临界区函数的使用

临界区函数在使用时以CRITICAL_SECTION结构对象保护共享资源,并分别用EnterCriticalSection()和LeaveCriticalSection()函数去标识和释放一个临界区。所用到的CRITICAL_SECTION结构对象必须经过InitializeCriticalSection()的初始化后才能使用,而且必须确保所有线程中的任何试图访问此共享资源的代码都处在此临界区的保护之下。否则临界区将不会起到应有的作用,共享资源依然有被破坏的可能。

(4)示例

#include "stdafx.h"#include <windows.h>#include <iostream>#include <process.h>using namespace std;CRITICAL_SECTION  cs;int i=0;unsigned int _stdcall myThread1(void*){EnterCriticalSection(&cs);while(i<10){cout<<"线程1正在运行!i="<<i++<<endl;}LeaveCriticalSection(&cs);return 0;}int _tmain(int argc, _TCHAR* argv[]){InitializeCriticalSection( &cs);HANDLE myHandle=(HANDLE)_beginthreadex(NULL,0,myThread1,NULL,0,NULL);EnterCriticalSection(&cs);cout<<"主线程正在运行!i="<<i++<<endl;LeaveCriticalSection(&cs);Sleep(100);DeleteCriticalSection(&cs);CloseHandle(myHandle);return 0;}

<2>MFC中临界区的使用

(1)MFC中头文件

"afxmt.h"

(2)MFC中的使用步骤

1)定义CCriticalSection类的一个全局对象(以使各个线程均能访问),

如CCriticalSectioncritical_section;

2)在访问需要保护的资源或代码之前,调用CCriticalSection类的成员Lock()获得临界区对象:

例如:critical_section.Lock();

在线程中调用该函数来使线程获得它所请求的临界区。如果此时没有其它线程占有临界区对象,则调用Lock()的线程获得临界区;否则,线程将被挂起,并放入到一个系统队列中等待,直到当前拥有临界区的线程释放了临界区时为止。

3)访问临界区完毕后,使用CCriticalSection的成员函数Unlock()来释放临界区:

例如:critical_section.Unlock();

再通俗一点讲,就是线程A执行到critical_section.Lock();语句时,如果其它线程(B)正在执行critical_section.Lock();语句后且critical_section.Unlock();语句前的语句时,线程A就会等待,直到线程B执行完critical_section. Unlock();语句,线程A才会继续执行。

(3)CCriticalSection源代码

 1)类声明

class CCriticalSection : public CSyncObjet{...public:CRITICAL_SECTION m_sect;public:BOOL Unlock();BOOL Lock();BOOL Lock(DWORD dwTimeout);...}
2)构造函数

CCriticalSection::CCriticalSection() : CSyncObject(NULL){ HRESULT hr = S_OK;if (!InitializeCriticalSectionAndSpinCount(&m_sect, 0))//可以理解为InitializeCriticalSection,为了效率,加了一个旋转锁。{hr =  HRESULT_FROM_WIN32(GetLastError());}if (FAILED(hr)){AtlThrow(hr);}}
3)Lock()定义

BOOL CCriticalSection::Lock(){::EnterCriticalSection(&m_sect); return TRUE; }
4)Unlock()定义

BOOL CCriticalSection::Unlock(){ ::LeaveCriticalSection(&m_sect); return TRUE; }
5)析构

CCriticalSection::~CCriticalSection(){ ::DeleteCriticalSection(&m_sect); }
   可以看出CCriticalSection类只是对win32中临界区函数的封装。在构造函数中调用InitializeCriticalSection()初始化临界区,在lock()函数中调用EnterCriticalSection()进入临界区,在Unlock()函数中调用LeaveCriticalSection()函数离开临界区,在析构函数中调用DeleteCriticalSection()函数释放临界区资源。







0 0
原创粉丝点击