本文主要是介绍scoped_lock,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
一个由于锁的作用域导致core dump的问题的解决
请看如下代码:
- void CCommParams::setParams( const char * authUser,
- const char * authPsw,
- const char * securityLevel,
- const char * portNumber)
- {
- boost::mutex::scoped_lock(m_runtimeMutex);
- std::string SecLevel = (NULL == securityLevel)? "" : securityLevel;
- std::string nPort = (NULL == portNumber)? 0 : atoi(portNumber);
- std::string AuthUsr = (NULL == authUser)? "" : authUser;
- std::string AuthPwd = (NULL == authPsw)? "" : authPsw;
- m_szSecLevel =SecLevel;
- m_szUsrName = authUser;
- m_szPwd =authPsw;
- m_dwPort = nPort;
- }
问题的提出:
在多线程环境下, 如果又多个线程同时调用以上函数setParams,发现总是core dump.
通过gdb bt发现,问题本质原因是由于多个线程对m_Usr等同时写入,如m_szUsrName = authUser,竞争导致的crash。
可奇怪的是,在写入或赋值前,我们已经加锁了啊!百思不得其解。
问题的解决:
通过走读代码,发现了一行可疑点:
boost::mutex::scoped_lock(m_runtimeMutex);
正常情况下,我们都是这样使用:
boost::mutex::scoped_lock Lock(m_runtimeMutex);
即会定义一个临时变量 Lock.
这2者有何不同呢。如果定义了Lock变量,那么它的作用域为整个函数域,即从{开始,到}结束,这样mutex就起到了保护数据同时写入竞争的作用;
那么是否没有Lock变量情况下,scoped_lock的作用域仅仅是到该行的“;”就结束了呢?
为了验证这个想法,我写了如下代码,通过对象何时析构来证实该想法:
- #include <stdio.h>
- #include <string>
- using namespace std;
- class my
- {
- public:
- my(const std::string & name)
- {
- m_name = name;
- printf("create [%s]\n", m_name.c_str());
- }
- virtual ~my()
- {
- printf("destroy [%s]\n", m_name.c_str());
- }
- private:
- std::string m_name;
- };
- int main(int argc, char** argv)
- {
- my("1");
- my tmp("2");
- printf("function end\n");
- return 0;
- }
boost::lexical_cast,mutex::scoped_lock,bind,function,signal的用法
(2016-08-08 13:12:49)c++数据类型万能转换器boost::lexical_cast .
boost::lexical_cast为数值之间的转换(conversion)提供了一揽子方案,比如:将一个字符串"123"转换成整数123,代码如下:
- string s = "123";
- int a = lexical_cast<<spanclass="datatypes">int>(s);
这种方法非常简单,笔者强烈建议大家忘掉std诸多的函数,直接使用boost::lexical_cast。如果转换发生了意外,lexical_cast会抛出一个bad_lexical_cast异常,因此程序中需要对其进行捕捉。
mutex::scoped_lock
发现某个函数对共享资源写入前调用的了该函数,但是没发现释放锁的地方,当时就理解为:此锁为智能锁,作l用域应该在函数内,函数调用完毕,锁会自动释放。
两种的区别,很常见的
boost::mutex::scoped_lock(m_runtimeMutex);没有临时变量
定义一个临时变量Lock. boost::mutex::scoped_lockLock(m_runtimeMutex);
这两个有何区别?不仅仅如此,很多场景都是如此。
这2者有何不同呢。如果定义了Lock变量,那么它的作用域为整个函数域,即从{开始,到}结束,这样mutex就起到了保护数据同时写入竞争的作用;
那么是否没有Lock变量情况下,scoped_lock的作用域仅仅是到该行的“;”就结束了呢?
- class my
- {
- public:
- my(const std::string & name)
- {
- m_name = name;
- printf("create [%s]\n", m_name.c_str());
- }
- virtual ~my()
- {
- printf("destroy [%s]\n", m_name.c_str());
- }
- private:
- std::string m_name;
- };
- int main(int argc, char** argv)
- {
- my("1");
- my tmp("2");
- printf("function end\n");
- return 0;
- }
- 果不其然,my("1")这个对象在分号;结束之后就进行了析构,而tmp对象直到main函数结束之后才析构。
boost里的bind,function,signal三个组件都是对用函数做参数(其他算法也用函数做参数),对函数的某一项进行操作。
bind主要是对函数参数的作用。
function主要是对函数地址的封装。
signal主要是异步回调。
用函数做参数时
1.普通函数需要传递函数地址。
2.函数对象需要传递一个对象
3.成员函数需要传递对象,指明所调用的成员函数。如果只有对象则符合规则2.
这篇关于scoped_lock的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!