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

Posted xianjian_x

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了一个由于锁的作用域导致core dump的问题的解决相关的知识,希望对你有一定的参考价值。

如果没定义局部变量 lock 那么生存周期几乎为0

请看如下代码:

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函数结束之后才析构。

原文地址:
http://blog.csdn.net/acs713/article/details/24290659

scoped_lock在遇到 sleep 时也会解锁

  有时候需要 boost::condition_variable 变量,在 cond 变量等待之前需要一个 lock 变量 :

m_cond.timed_wait(lock, cur_time + posix_time::seconds(1) );

此时可以用 boost::mutex 锁定来获取:(锁定的同时定义了一个局部变量lock)

boost::mutex::scoped_lock lock(m_lock);

  后面又需要 sleep 了,那么现在问题来了:在 sleep 之前是不是会自动解锁 m_lock ?
  这个一直没有查找到文档,还是写个小 demo 程序验证下:

void Test::run(void)

    while(1)
        boost::mutex::scoped_lock lock(m_lock);
        //m_lock.lock();

        printf("test\\\\\\\\n");
        Sleep(3);
    


void Test::start(void)

    boost::function0<void> g        = boost::bind(&Test::run, this);
    m_pRunThread                    = new boost::thread(g);

    if(m_pRunThread != NULL)
        boost::mutex::scoped_lock lock(m_lock);
        //m_lock.lock();

    Sleep(30000);

可以看到 在 Sleep 之前 m_lock 的确是得到了解锁。

以上是关于一个由于锁的作用域导致core dump的问题的解决的主要内容,如果未能解决你的问题,请参考以下文章

JavaScript 词法静态动态作用域初级理解

通过12334说说InnoDB里面的锁

通过12334说说InnoDB里面的锁

oracle数据库表被锁的解锁方法

php中在局部作用域内访问全局变量

关于Javascript作用域及作用域链的总结