Как видно из названия, Mutex - это recursive
, но Lock - нет.
Тем не менее, у вас есть проблема с дизайном. Было бы лучше, если бы операции блокировки были недоступны снаружи.
class SynchronizedInt
{
public:
explicit SynchronizedInt(int i = 0): mData(i) {}
int get() const
{
lock_type lock(mMutex);
toolbox::ignore_unused_variable_warning(lock);
return mData;
}
void set(int i)
{
lock_type lock(mMutex);
toolbox::ignore_unused_variable_warning(lock);
mData = i;
}
private:
typedef boost::recursive_mutex mutex_type;
typedef boost::unique_lock<mutex_type> lock_type;
int mData;
mutable mutex_type mMutex;
};
Суть recursive_mutex
состоит в том, чтобы разрешить цепную блокировку в данном потоке, которая может возникнуть, если у вас есть сложные операции, которые в некоторых случаях вызывают друг друга.
Например, давайте добавим твик get:
int SynchronizedInt::UnitializedValue = -1;
int SynchronizedInt::get() const
{
lock_type lock(mMutex);
if (mData == UnitializedValue) this->fetchFromCache();
return mData;
}
void SynchronizedInt::fetchFromCache()
{
this->set(this->fetchFromCacheImpl());
}
Где здесь проблема?
get
получает блокировку на mMutex
- звонит
fetchFromCache
звонит set
set
пытается получить замок ...
Если бы у нас не было recursive_mutex
, это бы не получилось.