Boost多线程异常



我有一个类似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("~MutexClassn");
boost::unique_lock<boost::shared_mutex> lock(m_mutex);
running = false;
}
void MutexClass::doSomeThing() {
printf("doSomeThingn");  //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;
}

当我用运行此文件时

g++main.cpp-lbox_system-lbox_thread-g-o main&amp/主

它显示

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

我知道它在第33行崩溃了,这是函数中的注释行

void MutexClass::doSomeThing() {
printf("doSomeThingn");  //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");
}    
}

环境:增强版本为1.54

我的问题是:程序是multiple-read/single-write,如果MutexClass已经运行析构函数,在其他线程中运行doSomeThing时,我如何避免这种情况
并且只能添加try/catch
谢谢!

有很多方法可以实现。这里的主要目标是不要delete您的对象,直到所有使用它的例程都失效为止。其中一种方法是使用shared_ptr将对象传递到线程中。

看看我在这里做了什么来使代码工作。我已经用评论了重大变化!!!

#include <stdio.h>
#include <boost/thread/shared_mutex.hpp>
#include <boost/thread.hpp>
#include <thread>
class MutexClass
{
private:
/* data */
boost::shared_mutex m_mutex;
bool running;   //The flag program should stop
public:
MutexClass(/* args */);
~MutexClass();
void doSomeThing();
void stop() {       // !!! changing running to false moves to this method
printf("stop()n");
boost::unique_lock<boost::shared_mutex> lock(m_mutex);
running = false;
}   
};
MutexClass::MutexClass(/* args */)
{
running = true;
printf("MutexClass()n");
}
MutexClass::~MutexClass()
{
printf("~MutexClassn");
}
void MutexClass::doSomeThing() {
printf("doSomeThingn");  //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");
}
else {
printf("not running!n");
}
}
void doSomeThing(std::shared_ptr<MutexClass> mtx) {
std::this_thread::sleep_for(std::chrono::seconds(3));
mtx->doSomeThing();
}
void destroy(std::shared_ptr<MutexClass> mtx) {
std::this_thread::sleep_for(std::chrono::seconds(2));
mtx->stop();        // !!! Stop instead of delete
}

int main(int argc, char* argv[])
{
auto mtx = std::make_shared<MutexClass>();  // !!! store mtx in shared ptr
boost::thread thrd1(&doSomeThing, mtx);
boost::thread thrd2(&destroy, std::move(mtx));  // !!! You can play with std::move here to see where your object is destroyed.
thrd1.join();
thrd2.join();
printf("after joinn");     // before this line mtx object should be destroyed
std::this_thread::sleep_for(std::chrono::seconds(5));
//sleep(5);
return 0;
}

最新更新