Boost多线程异常
Boost multithreading 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
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;
}
当我 运行 这个文件
g++ main.cpp -lboost_system -lboost_thread -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
我知道它在第 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");
}
}
环境:Boost 版本为 1.54
我的问题是:程序是multiple-read/single-write
,如果MutexClass已经运行析构函数。
而且只能加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("~MutexClass\n");
}
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");
}
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 join\n"); // before this line mtx object should be destroyed
std::this_thread::sleep_for(std::chrono::seconds(5));
//sleep(5);
return 0;
}
我有一个类似 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;
}
当我 运行 这个文件
g++ main.cpp -lboost_system -lboost_thread -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
我知道它在第 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");
}
}
环境:Boost 版本为 1.54
我的问题是:程序是multiple-read/single-write
,如果MutexClass已经运行析构函数。
而且只能加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("~MutexClass\n");
}
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");
}
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 join\n"); // before this line mtx object should be destroyed
std::this_thread::sleep_for(std::chrono::seconds(5));
//sleep(5);
return 0;
}