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

    xiaoxiao2025-03-19  12

    如果没定义局部变量 lock 那么生存周期几乎为0scoped_lock在遇到 sleep 时也会解锁

    如果没定义局部变量 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 的确是得到了解锁。

    转载请注明原文地址: https://ju.6miu.com/read-1297184.html
    最新回复(0)