关闭

BOOST锁机制(1)

标签: boost
85人阅读 评论(0) 收藏 举报
分类:

首先来看几个例子,这个几个例子都是错误的使用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

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:2096次
    • 积分:101
    • 等级:
    • 排名:千里之外
    • 原创:8篇
    • 转载:0篇
    • 译文:0篇
    • 评论:0条
    文章分类
    文章存档