您的位置:首页 > 其它

一个由于锁的作用域导致core dump的问题的解决

2014-04-22 11:35 471 查看
请看如下代码:

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;
}




果不其然,my("1")这个对象在分号;结束之后就进行了析构,而tmp对象直到main函数结束之后才析构。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐