C++ Boost多线程异常

C++ Boost多线程异常,c++,multithreading,boost,readwritelock,boost-exception,C++,Multithreading,Boost,Readwritelock,Boost Exception,我有一个像main.cpp #include <stdio.h> #include <boost/thread/shared_mutex.hpp> #include <boost/thread.hpp> class MutexClass { private: /* data */ boost::shared_mutex m_mutex; bool running; //The flag program should stop pu

我有一个像
main.cpp

#include <stdio.h>
#include <boost/thread/shared_mutex.hpp>
#include <boost/thread.hpp>

class MutexClass
{
private:
    /* data */
    boost::shared_mutex m_mutex;
    bool running;   //The flag program should stop
public:
    MutexClass(/* args */);
    ~MutexClass();
    void doSomeThing();
};

MutexClass::MutexClass(/* args */)
{
    running = true;
    printf("MutexClass()\n");
}

MutexClass::~MutexClass()
{
    printf("~MutexClass\n");
    boost::unique_lock<boost::shared_mutex> lock(m_mutex);
    running = false;
}

void MutexClass::doSomeThing() {
    printf("doSomeThing\n");  //In fact, here is a callback or loop

    boost::shared_lock<boost::shared_mutex> lock(m_mutex); //(1)Exception here
    if(running){
        printf("still running!\n");
    }    
}

void doSomeThing(MutexClass* mtx) {
    sleep(3);
    mtx->doSomeThing();
}

void destroy(MutexClass* mtx) {
    sleep(2);
    delete mtx;
    mtx = NULL;
}


int main(int argc, char* argv[])
{
    MutexClass* mtx = new MutexClass();
    boost::thread thrd1(&doSomeThing,mtx);
    boost::thread thrd2(&destroy,mtx);
    thrd1.join();
    thrd2.join();
    sleep(5);
    return 0;
}
#包括
#包括
#包括
类互斥类
{
私人:
/*资料*/
boost::shared_mutex m_mutex;
bool running;//标志程序应该停止
公众:
互斥类(/*args*/);
~MutexClass();
无效剂量();
};
MutexClass::MutexClass(/*args*/)
{
运行=真;
printf(“MutexClass()\n”);
}
MutexClass::~MutexClass()
{
printf(“~MutexClass\n”);
boost::唯一的_锁(m_互斥);
运行=错误;
}
void MutexClass::doSomeThing(){
printf(“doSomeThing\n”);//实际上,这里有一个回调或循环
boost::共享锁(mumutex);/(1)这里的异常
如果(正在运行){
printf(“仍在运行!\n”);
}    
}
void doSomeThing(MutexClass*mtx){
睡眠(3);
mtx->doSomeThing();
}
无效销毁(互斥类*mtx){
睡眠(2);
删除mtx;
mtx=NULL;
}
int main(int argc,char*argv[])
{
MutexClass*mtx=新的MutexClass();
boost::线程thrd1(&doSomeThing,mtx);
boost::线程thrd2(&destroy,mtx);
thrd1.join();
thrd2.join();
睡眠(5);
返回0;
}
当我用

g++main.cpp-lboost_系统-lboost_线程-g-o main&./main

它表明

MutexClass()
~MutexClass
doSomeThing
terminate called after throwing an instance of 'boost::exception_detail::clone_impl<boost::exception_detail::error_info_injector<boost::lock_error> >'
  what():  boost: mutex lock failed in pthread_mutex_lock: Invalid argument
Aborted
MutexClass()
~MutexClass
剂量
在抛出“boost::exception\u detail::clone\u impl”的实例后调用terminate
what():boost:pthread_mutex_lock中的互斥锁失败:参数无效
流产
我知道它会在函数中的注释行第33行崩溃

void MutexClass::doSomeThing() {
    printf("doSomeThing\n");  //In fact, here is a callback or loop

    boost::shared_lock<boost::shared_mutex> lock(m_mutex); //Exception here
    if(running){
        printf("still running!\n");
    }    
}
void MutexClass::doSomeThing(){
printf(“doSomeThing\n”);//实际上,这里有一个回调或循环
boost::shared_lock(m_mutex);//此处出现异常
如果(正在运行){
printf(“仍在运行!\n”);
}    
}
Env:Boost版本是1.54

我的问题是:程序是多读/单写的,如果MutexClass已经运行析构函数,那么在不同线程中运行doSomeThing时如何避免这种情况。
并且只能添加try/catch块?

谢谢

可以通过很多方法来实现。这里的主要目标是在使用对象的所有例程都死掉之前,不要删除对象。其中一种方法是使用
shared_ptr
将对象传递到线程中

看看我在这里做了些什么来让这段代码工作。我已经评论了这些重大的变化

#包括
#包括
#包括
#包括
类互斥类
{
私人:
/*资料*/
boost::shared_mutex m_mutex;
bool running;//标志程序应该停止
公众:
互斥类(/*args*/);
~MutexClass();
无效剂量();
void stop(){/!!!将运行更改为false将移动到此方法
printf(“停止()\n”);
boost::唯一的_锁(m_互斥);
运行=错误;
}   
};
MutexClass::MutexClass(/*args*/)
{
运行=真;
printf(“MutexClass()\n”);
}
MutexClass::~MutexClass()
{
printf(“~MutexClass\n”);
}
void MutexClass::doSomeThing(){
printf(“doSomeThing\n”);//实际上,这里有一个回调或循环
boost::共享锁(mumutex);/(1)这里的异常
如果(正在运行){
printf(“仍在运行!\n”);
}
否则{
printf(“未运行!\n”);
}
}
无效剂量测定法(标准::共享剂量mtx){
std::this_thread::sleep_for(std::chrono::seconds(3));
mtx->doSomeThing();
}
无效销毁(标准::共享\u ptr mtx){
std::this_thread::sleep_for(std::chrono::seconds(2));
mtx->stop();/!!!停止而不是删除
}
int main(int argc,char*argv[])
{
自动mtx=std::使_共享();/!!!将mtx存储在共享ptr中
boost::线程thrd1(&doSomeThing,mtx);
boost::thread thrd2(&destroy,std::move(mtx));/!!!您可以在此处使用std::move查看对象被销毁的位置。
thrd1.join();
thrd2.join();
printf(“连接后\n”);//此行之前,应销毁mtx对象
std::this_thread::sleep_for(std::chrono::seconds(5));
//睡眠(5);
返回0;
}

这似乎与您之前的问题完全相同