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;

Windows下(不用cygwin)NDK直接编译编译boost 1.55

我使用的是android-ndk-r9d版本,NDK在7以后就不需要依赖于cygwin了 1. boost官网下载boost_1_55_0.tar.gz,解压放在/sources下, 解压后的文件...
  • ly131420
  • ly131420
  • 2015年06月26日 11:41
  • 2965

BOOST安装或编译

Boost库是为C++语言标准库提供扩展的一些C++程序库的总称。 Boost库由Boost社区组织开发、维护。其目的是为C++程序员提供免费、同行审查的、可移植的程序库。Boost库可以与C+...
  • hollyholly5
  • hollyholly5
  • 2016年11月23日 15:53
  • 1196

mingw环境下boost库的编译和使用

首先到boost的网站上下载最新的BOOST源代码和编译好的JAM,地址:http://www.boost.org/users/download/ 。这里下载的是 boost-jam-3.1.17-1...
  • origin_lee
  • origin_lee
  • 2014年12月18日 09:34
  • 387

boost::thread编程-线程中断

thread的成员函数interrupt()允许正在执行的线程被中断,被中断的线程会抛出一个thread_interrupted异常,它是一个空类,不是std::exception或boost::ex...
  • anda0109
  • anda0109
  • 2014年12月15日 15:24
  • 4334

[Boost]boost的时间和日期处理日期的操作和时间的操作

参考  http://www.cnblogs.com/lidabo/p/3938978.html  http://www.cnblogs.com/lidabo/p/3938969.html ...
  • muyuxuebao
  • muyuxuebao
  • 2016年07月20日 21:10
  • 628

C++ Boost::bind函数包装器使用,boost::bind与伪函数的绑定使用

在我们使用stl的 一些算法的时候,比如find_if,for_each等,需要使用仿函数,如果仿函数有2个参数,但是算法需要一个一元的仿函数的时候,我们可以使用适配器,boost库中boost::b...
  • szqsdq
  • szqsdq
  • 2017年04月25日 22:43
  • 519

boost::assign(标准容器填充库)

boost::assign通过对"+="和","的重载非常方便的填充标准容器(std::vector,std::set,std::list,std::map),使用boost::assign需要#in...
  • u013524455
  • u013524455
  • 2014年02月15日 17:49
  • 1147

boost全平台编译方法

0.通用规则boost自带一套编译工具bjam,bjam本身是跨平台的,并且也要自行编译出来。在boost目录下有bootstrap.sh和bootstrap.bat两个脚本分别用来编译*nix和wi...
  • hursing
  • hursing
  • 2015年06月11日 12:00
  • 35176

boost::bind和占位符实现的原理(from AV BOOST)

boost.bind是个非常强大的工具,有了它,我们可以轻松的将不同模块的代码,从物理上分离,从而达到解耦的作用。 当你开始尝试使用boost.bind来进行编程的时候,你会发现自己不知不觉中贱...
  • will_hsbsch
  • will_hsbsch
  • 2014年06月06日 15:42
  • 977

运用打分和Boost优化Elasticsearch搜索结果

来自Optimizing Search Results in Elasticsearch with Scoring and Boosting 作者:Neil Alex 2015/03/18虽然es提供...
  • qq_19598855
  • qq_19598855
  • 2016年01月25日 17:18
  • 6295
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:BOOST锁机制(1)
举报原因:
原因补充:

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