BOOST锁机制(1)

来源:互联网 发布:什么叫网络教育 编辑:程序博客网 时间:2024/06/09 19:57

首先来看几个例子,这个几个例子都是错误的使用boost的mutex。根本原因是对加锁原理认识不清楚。
BAD1:
ShareData.h用于定义共享数据

#ifndef __SHARE_DATA_H__#define __SHARE_DATA_H__namespace BOOST_TEST{    class CShareData    {    public:        CShareData(int nValue);        virtual ~CShareData();        int AddValue();        void PrintValue();    private:        int     m_nValue;    };    typedef boost::shared_ptr<CShareData> CShareDataPtr;}#endif

ShareData.cpp

#include <iostream>#include "ShareData.h"#include "Log.h"using namespace BOOST_TEST;CShareData::CShareData(int nValue) : m_nValue(nValue){}CShareData::~CShareData(){}int CShareData::AddValue(){    return ++m_nValue;}void CShareData::PrintValue(){    ::std::cout << "value = " << m_nValue << ::std::endl;}

BoostMutexTestThreadA.h

#ifndef __BOOST_MUTEX_TEST_THREADA_H__#define __BOOST_MUTEX_TEST_THREADA_H__#include "ThreadCommon.h"#include "ShareData.h"namespace BOOST_TEST{    class CBoostMutexTestThreadA : public CTimerThreadBase    {    public:        CBoostMutexTestThreadA(CShareDataPtr ptrShareData);        virtual ~CBoostMutexTestThreadA();    public:        void ExecuteTask();    private:        boost::mutex m_objMutex;        CShareDataPtr m_ptrShareData;    };typedef boost::shared_ptr<CBoostMutexTestThreadA> CBoostMutexTestThreadAPtr;}#endif

BoostMutexTestThreadB.h用于打印共享数据

#ifndef __BOOST_MUTEX_TEST_THREAD_H__#define __BOOST_MUTEX_TEST_THREAD_H__#include "ThreadCommon.h"#include "ShareData.h"namespace BOOST_TEST{    class CBoostMutexTestThreadB : public CTimerThreadBase    {    public:        CBoostMutexTestThreadB(CShareDataPtr ptrShareData);        virtual ~CBoostMutexTestThreadB();    public:        void ExecuteTask();    private:        boost::mutex m_objMutex;        CShareDataPtr m_ptrShareData;    };    typedef boost::shared_ptr<CBoostMutexTestThreadB> CBoostMutexTestThreadBPtr;}#endif

BoostMutexTestThreadB.cpp

#include <iostream>#include "BoostMutexTestThreadB.h"using namespace BOOST_TEST;CBoostMutexTestThreadB::CBoostMutexTestThreadB(CShareDataPtr ptrShareData) : m_ptrShareData(ptrShareData), CTimerThreadBase("threadb",10){}CBoostMutexTestThreadB::~CBoostMutexTestThreadB(){}void CBoostMutexTestThreadB::ExecuteTask(){    boost::mutex::scoped_lock lock(m_objMutex);    ::std::cout << "threadB::data = " << m_ptrShareData->AddValue() << ::std::endl;//打印共享数据}

BoostMutexTestThreadA.h用于打印共享数据

#ifndef __BOOST_MUTEX_TEST_THREADA_H__#define __BOOST_MUTEX_TEST_THREADA_H__#include "ThreadCommon.h"#include "ShareData.h"namespace BOOST_TEST{    class CBoostMutexTestThreadA : public CTimerThreadBase    {    public:        CBoostMutexTestThreadA(CShareDataPtr ptrShareData);        virtual ~CBoostMutexTestThreadA();    public:        void ExecuteTask();    private:        boost::mutex m_objMutex;        CShareDataPtr m_ptrShareData;    };typedef boost::shared_ptr<CBoostMutexTestThreadA> CBoostMutexTestThreadAPtr;}#endif

BoostMutexTestThreadA.cpp

#include <iostream>#include "BoostMutexTestThreadA.h"using namespace BOOST_TEST;CBoostMutexTestThreadA::CBoostMutexTestThreadA(CShareDataPtr ptrShareData) : m_ptrShareData(ptrShareData), CTimerThreadBase("threadb", 10){}CBoostMutexTestThreadA::~CBoostMutexTestThreadA(){}void CBoostMutexTestThreadA::ExecuteTask(){    boost::mutex::scoped_lock lock(m_objMutex);    m_ptrShareData->PrintValue();}

main.cpp

    m_ptrShareData = boost::make_shared<CShareData>(10);    m_ptrBoostMutexThreadA1 = boost::make_shared<CBoostMutexTestThreadA>(m_ptrShareData);    m_ptrBoostMutexThreadB = boost::make_shared<CBoostMutexTestThreadB>(m_ptrShareData);    m_ptrBoostMutexThreadA1->Resume();    m_ptrBoostMutexThreadB->Resume();    return true;

运行结果出现两个并发错误
<1>共享数据增加错乱
<2>打印错乱
原因分析:
两个线程同时操作同一共享数据m_ptrShareData,加锁应该是对共享数据加锁。这句话包括两个意思
<1>数据是共享的,两个线程都能看到,操作的是一份数据。
<2>锁也是共享的,两个线程要同时抢同一把锁!注意是同一把锁,而上面例子犯得错误虽然两个线程都对共享数据加锁了,但是加的锁却是属于各自对象的,因此并没有对共享数据进行锁定。
为什么会打印错误?因为输入输出流也是共享的,也需要加锁保护。

BAD2:

    m_ptrShareData = boost::make_shared<CShareData>(10);    m_ptrBoostMutexThreadA1 = boost::make_shared<CBoostMutexTestThreadA>(m_ptrShareData);    m_ptrBoostMutexThreadA2 = boost::make_shared<CBoostMutexTestThreadA>(m_ptrShareData);    m_ptrBoostMutexThreadA1->Resume();    m_ptrBoostMutexThreadA2->Resume();    return true;

运行结果出现两个并发错误
<1>共享数据增加错乱
<2>打印错乱
虽然这次是用同一个CBoostMutexTestThreadA创建了两个线程对象,但是这两个线程对象的锁仍是属于各自的,对共享数据加的锁对另一个线程而言无效。
正确的方式:
ShareData.h

#ifndef __SHARE_DATA_H__#define __SHARE_DATA_H__#include "Log.h"namespace BOOST_TEST{    class CShareData    {    public:        CShareData(int nValue);        virtual ~CShareData();        void AddValue();    private:        boost::mutex m_objMutex;        int     m_nValue;    };    typedef boost::shared_ptr<CShareData> CShareDataPtr;}#endif

ShareData.cpp

#include <iostream>#include "ShareData.h"#include "Log.h"using namespace BOOST_TEST;CShareData::CShareData(int nValue) : m_nValue(nValue){}CShareData::~CShareData(){}void CShareData::AddValue(){    boost::mutex::scoped_lock lock(m_objMutex);    ::std::cout << "value = " << m_nValue++ << ::std::endl;}

BoostMutexTestThreadA.cpp

#include <iostream>#include "BoostMutexTestThreadA.h"using namespace BOOST_TEST;CBoostMutexTestThreadA::CBoostMutexTestThreadA(CShareDataPtr ptrShareData) : m_ptrShareData(ptrShareData), CTimerThreadBase("threadb", 10){}CBoostMutexTestThreadA::~CBoostMutexTestThreadA(){}void CBoostMutexTestThreadA::ExecuteTask(){    m_ptrShareData->AddValue();}

BoostMutexTestThreadB.cpp

#include <iostream>#include "BoostMutexTestThreadB.h"using namespace BOOST_TEST;CBoostMutexTestThreadB::CBoostMutexTestThreadB(CShareDataPtr ptrShareData) : m_ptrShareData(ptrShareData), CTimerThreadBase("threadb",10){}CBoostMutexTestThreadB::~CBoostMutexTestThreadB(){}void CBoostMutexTestThreadB::ExecuteTask(){    m_ptrShareData->AddValue();}
    m_ptrShareData = boost::make_shared<CShareData>(10);    m_ptrBoostMutexThreadA1 = boost::make_shared<CBoostMutexTestThreadA>(m_ptrShareData);    m_ptrBoostMutexThreadA2 = boost::make_shared<CBoostMutexTestThreadA>(m_ptrShareData);    m_ptrBoostMutexThreadB = boost::make_shared<CBoostMutexTestThreadB>(m_ptrShareData);    m_ptrBoostMutexThreadA1->Resume();    m_ptrBoostMutexThreadA2->Resume();    m_ptrBoostMutexThreadB->Resume();    return true;
0 0
原创粉丝点击