BOOST锁机制(1)

原创 2016年06月01日 00:28:41

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

相关文章推荐

java concurrent (1): 锁机制

JDK5之前多线程的锁都是使用synchronized ,JDK 5中的锁是接口java.util.concurrent.locks.Lock。另外java.util.concurrent.locks...
  • ykdsg
  • ykdsg
  • 2011年12月17日 00:48
  • 1098

深入浅出 Java Concurrency (6): 锁机制 part 1

from:http://www.blogjava.net/xylz/archive/2010/07/05/325274.html 前面的章节主要谈谈原子操作,至于与原子操作一些相关的...
  • STU756
  • STU756
  • 2015年05月21日 14:12
  • 619

全面解析oracle中的锁机制1

1、锁的理解: 一般来说,以我现有的知识理解锁,可能认为锁是针对数据行,或者数据表的,但是oracle中对锁的适用范围是对所有oracle内的共享资源,比如,一个存储过程,一个触发器。。。当你在用这...

深入JVM锁机制1-synchronized

JVM锁,synchronized,Lock,自选锁,偏向锁,Cache一致性,Cache一致性流量,SMP

juc:并发编程1-锁机制

java concurrent

《深入浅出 Java Concurrency》—锁机制(八) 读写锁 (ReentrantReadWriteLock) (1)

转自:http://www.blogjava.net/xylz/archive/2010/07/14/326080.html从这一节开始介绍锁里面的最后一个工具:读写锁(ReadWriteLock)。...
  • FG2006
  • FG2006
  • 2011年05月05日 19:17
  • 1884

深入JVM锁机制(1) - synchronized

原文链接:http://blog.csdn.net/chen77716/article/details/6618779        最近开始学习Java,转载的都是个人觉得不错的文章,请原作者...
  • Don211
  • Don211
  • 2012年02月20日 11:16
  • 336

oracle锁机制探讨

  • 2012年09月24日 16:40
  • 95KB
  • 下载

Oracle数据库中的锁机制

数据库是一个多用户使用的共享资源。当多个用户并发地存取数据时,在数据库中就会产生多个事务同时存取同一数据的情况。若对并发操作不加控制就可能会读取和存储不正确的数据,破坏数据库的一致性。 在数据库中有...
  • liuyiy
  • liuyiy
  • 2014年05月04日 22:09
  • 8120
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:BOOST锁机制(1)
举报原因:
原因补充:

(最多只允许输入30个字)