`

临界区(Critical Section)的封装和使用示例

 
阅读更多
转自
http://www.cnblogs.com/sixbeauty/p/3951406.html

    这个做法其实是抄我老大的。服务器中,多线程经常需要使用临界区,为了简化代码的使用,把临界区封装为 CThreadLockHandle  类,通过封装,使用临界区资源每次只需要一行代码,而且只要确定对象的生存周期,就能完成对临界区资源的自动释放:

头文件:
//thread_lock.h
#ifndef THREAD_LOCK_HEAD_FILE
#define THREAD_LOCK_HEAD_FILE
#include<windows.h>
////////////////////////////////////////////////////////////////////////////

//临界区同步类
class CThreadLock
{
    //变量定义
private:
    CRITICAL_SECTION                m_csLock;            //临界区变量

    //函数定义
public:
    //构造函数
    inline CThreadLock() {    ::InitializeCriticalSection(&m_csLock);    };
    //析构函数
    inline ~CThreadLock() {    ::DeleteCriticalSection(&m_csLock);    };

    //功能函数
public:
    //锁定函数
    inline void Lock() {    ::EnterCriticalSection(&m_csLock); };
    //解锁函数
    inline void UnLock() {    ::LeaveCriticalSection(&m_csLock); };
};

////////////////////////////////////////////////////////////////////////////

//安全同步锁定句柄
class CThreadLockHandle
{
    //变量定义
private:
    int                                m_nLockCount;        //锁定计数
    CThreadLock                        *m_pThreadLock;        //锁定对象

    //函数定义
public:
    //构造函数
    CThreadLockHandle(CThreadLock *pThreadLock, bool bAutoLock=true);
    //析构函数
    virtual ~CThreadLockHandle();

    //功能函数
public:
    //锁定函数
    void Lock();
    //解锁函数
    void UnLock();
    //火枪锁定次数
    int inline GetLockCount() {    return m_nLockCount; };
};

#endif


源文件:
//thread_lock.cpp   programed by sany
//2014.9.2
//callme:sanyue9394@163.com


#include "thread_lock.h"
#include<assert.h>
////////////////////////////////////////////////////////////////////////////

//安全同步锁定句柄
//构造函数
CThreadLockHandle::CThreadLockHandle(CThreadLock *pThreadLock, bool bAutoLock)
{
    assert(pThreadLock!=NULL);
    m_nLockCount=0;
    m_pThreadLock=pThreadLock;
    if(bAutoLock)    Lock();
    return;
}
//析构函数
CThreadLockHandle::~CThreadLockHandle()
{
    while(m_nLockCount>0) UnLock();                                //生存周期结束自动解锁
}

//锁定函数
void CThreadLockHandle::Lock()
{
    //校验状态
    assert(m_nLockCount>=0);
    assert(m_pThreadLock!=NULL);

    //锁定对象
    m_nLockCount++;
    m_pThreadLock->Lock();
}

//解锁函数
void CThreadLockHandle::UnLock()
{
    //校验状态
    assert(m_nLockCount>0);
    assert(m_pThreadLock!=NULL);

    //解除状态
    m_nLockCount--;
    m_pThreadLock->UnLock();
}


经过这个类的封装,使用临界区实现线程同步只需要2步:

1.初始化一个全局的 CThreadLock 对象,为后面调用做准备。

2.每当需要使用临界区时,在作用域中声明一个局部变量:CThreadLockHandle ,当其生存周期结束时,将自动释放临界区资源


使用例子:
#include<stdio.h>
#include<windows.h>
#include <process.h> 
#include"thread_lock.h"

const int aSize=10;
char szArr[aSize+1]={};

CThreadLock                        threadLock;                            //声明CThreadLock类型的全局变量

unsigned _stdcall threadFunc1(void*)
{
    CThreadLockHandle lockHandle(&threadLock);                        //需要使用临界区是,声明一个CThreadLockHandle类型的变量,其生存周期结束自动解锁
    for(int s=0;s<aSize;s++)
    {
        szArr[s]='a';
        Sleep(1);
    }
    return 0;
}

unsigned _stdcall threadFunc2(void*)
{
    CThreadLockHandle lockHandle(&threadLock);                        //需要使用临界区是,声明一个CThreadLockHandle类型的变量,其生存周期结束自动解锁
    for(int s=0;s<aSize;s++)
    {
        szArr[aSize-1-s]='b';
        Sleep(1);
    }
    return 0;
}

int main()
{
    memset(szArr,0,sizeof(szArr));
    HANDLE handle1=(HANDLE)_beginthreadex(NULL,0,threadFunc1,NULL,0,0);
    HANDLE handle2=(HANDLE)_beginthreadex(NULL,0,threadFunc2,NULL,0,0);

    WaitForSingleObject(handle1,INFINITE);
    WaitForSingleObject(handle2,INFINITE);

    printf("%s\n",szArr);
    CloseHandle(handle1);
    CloseHandle(handle2);

    return 0;
}


如果在类中调用,把CThreadLock 对象声明为私有或保护成员即可:
class threadtest
{
protected:
    static CThreadLock                        m_ThreadLock;                //线程锁

public:
    static unsigned _stdcall threadFunction(void* pThreadData);
};
unsigned _stdcall threadtest::threadFunction(void* pThreadData)
{
    CThreadLockHandle lockHandle(&m_ThreadLock);                //生存周期结束自动解锁
    //doSomething
    return 0;
}



附:http://www.cnblogs.com/userinterface/archive/2005/04/27/146137.html    不错的线程同步文章
分享到:
评论

相关推荐

    CriticalSection.rar_CriticalSection

    临界区(CriticalSection)是Windows操作系统中用于多线程编程的一种同步机制,它允许一个时间段内只有一线程访问特定的资源或代码段,从而防止数据竞争和其他并发问题。在微软的面试中,理解并能熟练运用临界区API...

    CriticalSection.rar_CCriticalSection_CriticalSection

    在`CriticalSection.cpp`源文件中,我们通常会看到如下的使用示例: ```cpp #include #include CComCritSecLock lock(cs); // cs 是 CCriticalSection 对象 // 在这里,临界区开始 try { // 访问共享资源的代码...

    使用临界区对象(CriticalSeciton)实现线程同步

    - CriticalSection对象是Windows提供的一个内核对象,用于管理临界区,提供了线程安全的进入和离开临界区的机制。 - 与互斥量(Mutex)相比,临界区的使用更高效,因为它的所有权仅限于同一进程内的线程,减少了...

    利用临界区同步线程例子

    临界区(Critical Section)是一种有效的同步机制,用于控制多个线程对共享资源的访问,防止数据竞争和不一致。本示例将详细介绍如何在Delphi 7环境下,通过使用临界区来同步三个线程,并将此功能封装到一个类中,...

    windows程序设计

    在学习和实践中,通过分析压缩包中的"03CriticalSection"文件,你可以看到如何在实际代码中使用临界区进行线程同步。这些示例代码可以帮助理解临界区的工作原理,以及如何在MFC应用程序中正确地管理和使用它们,从而...

    临界区和条件变量实现读写者问题

    3. `CriticalSection`类:封装临界区和条件变量的管理,提供`enter()`和`exit()`方法供读写者调用。 4. 可能还会有主程序,创建读写者线程并启动它们。 通过这种方式,我们利用临界区确保了并发访问的互斥性,而...

    使用临界区线程同步示例代码VC源代码

    本示例代码是使用VC++(Visual C++)和MFC(Microsoft Foundation Classes)库来实现的,它展示了如何使用`CCriticalSection`类来管理临界区。 首先,`CCriticalSection`是MFC对Windows API中的`CRITICAL_SECTION`...

    信号量与互斥锁示例代码

    2. **互斥锁**:互斥锁是一种更简单的同步原语,它确保同一时间只有一个进程能够访问特定的临界区(Critical Section)。当一个进程进入临界区时,它会锁定互斥锁,其他试图进入临界区的进程会被阻塞,直到当前进程...

    多线程编程四-线程同步.pdf

    紧接着,文档引入了临界区(CriticalSection)的概念。临界区是一个简单而强大的同步原语,它仅限于同步一个进程内的线程访问。与互斥量不同,临界区不使用句柄,因此在同步时可能更快。文档描述了如何在MFC中创建和...

    Chronothread_delphi_

    TThread是VCL(Visual Component Library)框架的一部分,它封装了Windows API中的线程创建和管理功能。首先,你需要创建一个新的TThread类的子类,并重写Execute方法,这是线程执行的主要代码块。例如: ```delphi...

    操作系统概念英文课件:Chapter 06-process synchronization.pptx

    **临界区问题(The Critical-Section Problem)** 临界区问题的核心是确保当多个进程访问共享资源时,只有一个进程能够执行相关的代码段,即临界区。临界区的执行必须满足四个条件:互斥、请求与退出、让权等待和...

    MFC多线程编程实例

    `CRITICAL_SECTION`结构体和`EnterCriticalSection`/`LeaveCriticalSection`函数组合使用,可实现临界区的锁定和解锁。 - **事件(Event)**:事件对象可以用来通知线程有特定事件发生,例如`CreateEvent`创建事件,...

    它使用了同步对象保护线程请求的数据.zip_数据 线程

    同步对象,如C_criticalSection(这是微软MFC库中的一个类),是用来防止多个线程同时访问同一资源,从而避免数据竞争和不一致的情况。 描述中提到,这个ISAPI应用是用Visual C++ 4.1编写的,这是一款经典的开发...

    c++线程加锁.pdf

    在给定的文档中,讨论了如何在C++中使用Win32 API实现线程锁,特别是通过临界区(CRITICAL_SECTION)来管理并发访问。 临界区是Windows API提供的一种同步原语,它确保同一时间只有一个线程能够执行特定的代码块。...

    2个线程同时运行实例MFC

    临界区(CriticalSection)是一种简单的同步机制,它只允许一个线程进入并执行,其他线程必须等待。在MFC中,我们可以通过CRITICAL_SECTION类来实现。当一个线程开始修改共享数据时,它会锁定临界区,其他试图访问该...

    vc多线程编程的多个实例

    `CCriticalSection`是MFC对Windows API的`CRITICAL_SECTION`结构的封装。 2. **事件(CEvent)**:事件是一种通知机制,允许一个或多个线程等待特定条件的发生。事件有两种状态:有信号状态和无信号状态。线程可以...

    MFC 多线程实例.rar

    开发者可能在代码中定义了CRITICAL_SECTION对象,并在需要访问共享资源的地方使用EnterCriticalSection和LeaveCriticalSection函数来进入和离开临界区。 在压缩包文件名称列表中提到的"CThreadEx"可能是创建的...

    多线程参考代码 《Windows多线程编程技术与实例》-郝文化-源代码-3316.rar

    线程锁是另一种同步工具,包括互斥量(Mutex)、临界区(Critical Section)和读写锁(Read-Write Lock)。这些锁机制用于保护临界区,防止多个线程同时进入,避免数据竞争和不一致。例如,互斥量适用于需要独占访问...

    使用互斥进行线程同步代码示例VC源代码

    在VC++中,我们可以使用CRITICAL_SECTION结构来实现临界区。在MFC中,CMutex可以作为临界区的一种实现方式。 2. **信号量(Semaphore)**:与互斥量类似,但信号量可以控制同时访问资源的线程数量。它有一个计数值...

Global site tag (gtag.js) - Google Analytics