Я реализовал макрос блокировки на основе мьютекса boost, код ниже:
#include <boost/thread.hpp>
#include <iostream>
#define LOCK(x) if(Lock _lock_=x){}else
class Mutex{
public:
friend class Lock;
private:
boost::mutex mutex_;
void Lock(){
mutex_.lock();
};
void Unlock(){
mutex_.unlock();
};
};
class Lock{
public:
Lock(Mutex& mutex):mutex_(mutex){mutex_.Lock();};
~Lock(){mutex_.Unlock();};
operator bool() const {
return false;
}
private:
Mutex& mutex_;
};
void wait(int seconds)
{
boost::this_thread::sleep(boost::posix_time::seconds(seconds));
}
Mutex mtx;
void thread()
{
for (int i = 0; i < 5; ++i)
{
LOCK(mtx){
wait(1);
std::cout << "Thread " << boost::this_thread::get_id() << ": " << i << std::endl;
}
}
}
int main()
{
boost::thread t1(thread);
boost::thread t2(thread);
t1.join();
t2.join();
}
Я скомпилировал его в Mac OS, используя clang++ -std=c++11 -stdlib=libc++ lock_raii.cc -lboost_system -lboost_thread
. Когда я запускаю его, возникает Segmentation fault: 11
.
В чем проблема?
Помимо того, что этот метод по крайней мере сомнительный, я не вижу проблемы с кодом. gcc v4.7.0 на Linux тоже не имеет проблем (отсутствует ошибка сегментации). Таким образом, вы не можете настроить настройку должным образом или где-нибудь найти ошибку. Вы должны запустить свою программу под отладчиком и посмотреть, где эта проблема. Теоретически этот код:
if(Lock _lock_=x){}else
может быть скомпилирован как:
if(Lock _lock_= Lock(x) ){}else
и вызывать копирование ctor и иметь двойную разблокировку на мьютексе. Чтобы убедиться, что это не проблема, сделайте copy ctor для класса Lock private.
Lock _lock_=x
будет некорректным и не скомпилируется. Короче говоря, дизайн сломан, решение состоит в том, чтобы изменить его.