多线程临界区编程

一、实现的技术如下:

1、以对象管理资源(例如:临界区),即资源获得即初始化(RAII)。

2、防止异常逃出析构函数,即必须捕捉析构函数产生的异常。

3、恰好足够线程安全。

二、以对象管理资源:

1、不以对象管理资源分析:

       以CCriticalSection类(见附录源码)为例分析如下:

   (a)、该类可以实现临界区管理功能,具体功能如下:

       <1>、临界区的初始化(Init())。

       <2>、临界区上锁(Lock())。

       <3>、临界区解锁(Unlock())。

       <4>、临界区的删除(Term())。

  (b)、该类的不足如下:

        <1>、用户可能在没有初始化临界区之前使用该临界区。

例如:在没有初始化前,对临界区做上锁、解锁或者删除临界区,这都会使程序崩溃。

        <2>、用户可能在删除临界区后继续使用该临界区。

例如:在临界区被删除后,对临界区做上锁或者解锁操作,这会导致程序崩溃。

        <3>、用户可能忘记删除不再使用的临界区。

例如:在临界区不再使用后忘记删除,这会产生内存泄漏。

<4>、用户对临界区上锁后,可能忘记解锁或者在解锁前程序产生异常,这都可能导致该临界区一直处于上锁状态,使其他用户无法访问被临界区上锁的数据,这也会产生无法删除临界区的内存泄漏。

2、以对象管理资源分析如下:

(a)、以CAutoCriticalSection类(见附录源码)为例分析如下:

该类的可以实现CCriticalSection的功能,同时还可以克服该类的不足。

该类的优点如下:

<1>、保证在使用该临界区之前初始化改临界区。

使用的技术为:资源获得即初始化,即在该类的构造函数中初始化临界区。

        <2>、不会产生因用户忘记删除临界区而产生内存泄漏。

实现方法为:在该函数的析构函数中删除不再使用的临界区。

         <3>、在用户删除临界区后,不会再使用临界区。

实现方法为:在使用临界区前先判断该临界区是否还存在,若存在可以继续使用,若不存在就不再使用。

    (b)、以CObjectLockT类(源码见附录)为例分析如下:

该类可以实现对CAutoCriticalSection类的管理,从而可以防止忘了解锁的危险。

实现方法:在该类的构造函数里对临界区上锁,在析构函数里对临界区解锁。

原因:当离开该类对象的作用域或者产生异常时都会调用该类对象的析构函数,因此可以保证干临界区的解锁。

三、析构函数和异常

1、析构函数不捕获异常

   在析构函数产生异常时,若此时捕获就不再有捕获的时机,那么程序就会崩溃,用回也不会明白程序崩溃的原因。

2、在析构函数中捕获异常

   在必须在析构函数捕获异常,当产生异常时捕获异常,从而可以记下产生异常的原因,还可以让程序正常终止。

3、              对外提供Term()函数的原因

既然在析构函数调用该函数,那么对外提供该函数的原因是什么?

<1>、给用户一个随时删除临界区的权利,可以实现当临界区不再使用时随时删除,节省内存的使用。

<2>、给用户提供该函数的目的是给用户一个自己处理错误的机会,若用户认为该函数不会产生异常或者错误,那么当在析构函数调用该函数产生错误或异常时用户将无法再抱怨我们没有给他处理错误的机会。

四、线程安全

通过给CObjectRootEx模板类传递不同的类(CMultiThreadModel和CSingleThreadModel)从而可以恰好足够线程安全的控制。

1、              以CSingleThreadModel类为CObjectRootEx类的模板参数。

当为客户的程序上锁,即调用Lock()时,那么最终调用的为CFakeCriticalSection类的Lock(),该类的Lock没有做任何实现,仅仅是简单返回。解锁也一样。

2、              以CMultiThreadModel类为CObjectRootEx类的模板参数。

当为客户的程序上锁,即调用Lock()时,那么最终调用的为CCriticalSection类的Lock(),从而实现对临界区的上锁,可以防止多个线程的同时访问。解锁也一样。

总结:

1、        若确信自己的程序不在多线程的环境下运行,那么可以使自己的程序继承CObjectRootEx类,并以CSingleThreadModel类为参数,这在现在看起来或许有点多余。

2、        直到某一天自己的程序要运行在多线环境下,那么只需要以CMultiThreadModel类替换CSingleThreadModel类,其他的什么也不用变化,就可以实现线程同步访问公共数据。

 

 

 

附录:

/

//Asynchronous code

#ifndef ASYN_H_

#define ASYN_H_

class CCriticalSection

{

public:

    CCriticalSection()throw()

    {  

        memset(&m_sec, 0, sizeof(CRITICAL_SECTION));

    }

    virtual ~CCriticalSection()

    {

    }

    HRESULT Lock()throw()

    {

        EnterCriticalSection(&m_sec);

        return S_OK;

    }

    HRESULT Unlock()throw()

    {

        LeaveCriticalSection(&m_sec);

        return S_OK;

    }

    HRESULT Init()throw()

    {

        HRESULT hRes = E_FAIL;

        try

        {

            InitializeCriticalSection(&m_sec);

            hRes = S_OK;

        }

        catch ( ... )

        {

            hRes = E_OUTOFMEMORY;

        }

        return hRes;

    }

    HRESULT Term() throw()

    {

        DeleteCriticalSection(&m_sec);

        return S_OK;

    }

private:

    CRITICAL_SECTION m_sec;

};

 

class CAutoCriticalSection : public CCriticalSection

{

public:

    CAutoCriticalSection()

        : m_bTermed(true)

    {

        HRESULT hr = CCriticalSection::Init();

        if ( FAILED(hr) )

        {

            throw hr;

        }

        m_bTermed = false;

    }

    ~CAutoCriticalSection()throw()

    {

        try

        {

            Term();

        }

        catch ( ... )

        {

 

        }

    }

    HRESULT Term()throw()

    {

        HRESULT hRes = S_OK;

        if ( !m_bTermed )

        {

            m_bTermed = true;

            hRes = CCriticalSection::Term();

        }

        return hRes;

    }

private:

    HRESULT Init();

private:

    bool m_bTermed;

};

class CSafeDeleteCriticalSection : public CCriticalSection

{

public:

    CSafeDeleteCriticalSection()

        : m_bInitialized(false)

    {

    }

    ~CSafeDeleteCriticalSection()throw()

    {

        try

        {

            Term();//Derived class

        }

        catch ( ... )

        {

            //log

        }

    }

    HRESULT Init()throw()

    {

        HRESULT hr = CCriticalSection::Init();

        if ( SUCCEEDED(hr) )

        {

            m_bInitialized = true;

        }

        return hr;

    }

    HRESULT Term()throw()

    {

        HRESULT hRes = S_OK;

        if ( m_bInitialized )

        {

            m_bInitialized = false;

            hRes = CCriticalSection::Term();

        }

        return hRes;

    }

    HRESULT Lock()throw()

    {

        HRESULT hRes = S_OK;

        if ( m_bInitialized )

        {

            hRes = CCriticalSection::Lock();

        }

        return hRes;

    }

    HRESULT Unlock()throw()

    {

        HRESULT hRes = S_OK;

        if ( m_bInitialized )

        {

            hRes = CCriticalSection::Unlock();

        }

        return hRes;

    }

private:

    bool m_bInitialized;

};

 

class CFakeCriticalSection

{

public:

    HRESULT Lock() throw() { return S_OK; }

    HRESULT Unlock() throw() { return S_OK; }

    HRESULT Init() throw() { return S_OK; }

    HRESULT Term() throw() { return S_OK; }

};

 

class CMultiThreadModel

{

public:

    typedef CAutoCriticalSection AutoDeleteCriticalSection;

};

 

class CSingleThreadModel

{

public:

    typedef CFakeCriticalSection AutoDeleteCriticalSection;

};

 

//foward declaration

template < typename ThreadModel >

class CObjectLockT;

 

template < typename ThreadModel >

class CObjectRootEx

{

public:

    typedef typename ThreadModel::AutoDeleteCriticalSection _AutoDelCritSec;

    typedef CObjectLockT<ThreadModel> ObjectLock;

public:

    void Lock()

    {

        m_critsec.Lock();

    }

    void Unlock()

    {

        m_critsec.Unlock();

    }

private:

    _AutoDelCritSec m_critsec;

};

 

template < typename ThreadModel >

class CObjectLockT

{

public:

    CObjectLockT(CObjectRootEx<ThreadModel>* p)

        : m_p(p)

        , m_bUnlocked(false)

    {

        if ( m_p )

        {

            m_p->Lock();

        }

    }

    ~CObjectLockT()

    {

        try

        {

            Term();

        }

        catch ( ... )

        {

            //Prevent exception leak out from deconstruction

        }

    }

 

    void Term()throw()

    {

        if ( !m_bUnlocked )

        {

            if ( m_p )

            {

                m_p->Unlock();

            }

            m_bUnlocked = true;

        }

    }

private:

    CObjectLockT(const CObjectLockT&);

    CObjectLockT& operator==(const CObjectLockT&);//

private:

    CObjectRootEx<ThreadModel>* m_p;

    bool m_bUnlocked;

};

 

#endif

 

 

//

///以下为测试代码

#include <iostream>

#include <windows.h>

#include "asyn.h"

using namespace std;

///

///Test Code

//

class CTestClass

    : public CObjectRootEx < CSingleThreadModel >  //Test not asynchronous

    //:public CObjectRootEx < CMultiThreadModel >  //Test asynchronous

{

public:

    void TestFunc();

};

void CTestClass::TestFunc()

{

    ObjectLock clObjectLock(this);  //Lock

    cout << "CTestClass::TestFunc come in" << endl;

    ///Other code

    ///Your data does't be visited by multithread at the same time.

    Sleep(3000);//Test Lock

    cout << "Sleep over" << endl;

}

 

 

CTestClass clCTestClass;

DWORD ThreadProc(

                 LPVOID lpParameter

                 )

{

    clCTestClass.TestFunc(); //Test Thread visit

    return 0;

}

void main()

{

    DWORD dwThreadID = 0;

    CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)&ThreadProc, NULL, 0, &dwThreadID);

    clCTestClass.TestFunc();//Main Thread visit

    Sleep(5000);

}

 

本文来自CSDN博客,出处:http://blog.csdn.net/firststudy/archive/2009/03/01/3946294.aspx

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
【优质项目推荐】 1、项目代码均经过严格本地测试,运行OK,确保功能稳定后才上传平台。可放心下载并立即投入使用,若遇到任何使用问题,随时欢迎私信反馈与沟通,博主会第一时间回复。 2、项目适用于计算机相关专业(如计科、信息安全、数据科学、人工智能、通信、物联网、自动化、电子信息等)的在校学生、专业教师,或企业员工,小白入门等都适用。 3、该项目不仅具有很高的学习借鉴价值,对于初学者来说,也是入门进阶的绝佳选择;当然也可以直接用于 毕设、课设、期末大作业或项目初期立项演示等。 3、开放创新:如果您有一定基础,且热爱探索钻研,可以在此代码基础上二次开发,进行修改、扩展,创造出属于自己的独特应用。 欢迎下载使用优质资源!欢迎借鉴使用,并欢迎学习交流,共同探索编程的无穷魅力! 基于业务逻辑生成特征变量python实现源码+数据集+超详细注释.zip基于业务逻辑生成特征变量python实现源码+数据集+超详细注释.zip基于业务逻辑生成特征变量python实现源码+数据集+超详细注释.zip基于业务逻辑生成特征变量python实现源码+数据集+超详细注释.zip基于业务逻辑生成特征变量python实现源码+数据集+超详细注释.zip基于业务逻辑生成特征变量python实现源码+数据集+超详细注释.zip基于业务逻辑生成特征变量python实现源码+数据集+超详细注释.zip 基于业务逻辑生成特征变量python实现源码+数据集+超详细注释.zip 基于业务逻辑生成特征变量python实现源码+数据集+超详细注释.zip
提供的源码资源涵盖了安卓应用、小程序、Python应用和Java应用等多个领域,每个领域都包含了丰富的实例和项目。这些源码都是基于各自平台的最新技术和标准编写,确保了在对应环境下能够无缝运行。同时,源码中配备了详细的注释和文档,帮助用户快速理解代码结构和实现逻辑。 适用人群: 这些源码资源特别适合大学生群体。无论你是计算机相关专业的学生,还是对其他领域编程感兴趣的学生,这些资源都能为你提供宝贵的学习和实践机会。通过学习和运行这些源码,你可以掌握各平台开发的基础知识,提升编程能力和项目实战经验。 使用场景及目标: 在学习阶段,你可以利用这些源码资源进行课程实践、课外项目或毕业设计。通过分析和运行源码,你将深入了解各平台开发的技术细节和最佳实践,逐步培养起自己的项目开发和问题解决能力。此外,在求职或创业过程中,具备跨平台开发能力的大学生将更具竞争力。 其他说明: 为了确保源码资源的可运行性和易用性,特别注意了以下几点:首先,每份源码都提供了详细的运行环境和依赖说明,确保用户能够轻松搭建起开发环境;其次,源码中的注释和文档都非常完善,方便用户快速上手和理解代码;最后,我会定期更新这些源码资源,以适应各平台技术的最新发展和市场需求。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值