I have a program like 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;
}
when I run this file with
g++ main.cpp -lboost_system -lboost_thread -g -o main && ./main
It shows
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
I know it crash at line 33, the comment line in the function
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");
}
}
Env: Boost Version is 1.54
My question is: The program is multiple-read/single-write, how can I avoid this when run doSomeThing in a different thread, if the MutexClass already run destructor.
And only can add try/catch block?
Thanks!
It can be done by plenty of ways. The main goal here is not to
deleteyour object until all the routines using it are dead. One of the method is usingshared_ptrto pass the object into thread.Take a look at what I'd done here to make this code work. I've commented the significant changes with !!!