1.概述
锁机制是多线程并发情景下一种控制共享资源访问的同步机制。Mutex与FastMutex相似,它们都可以借助ScopedLock模板类来自动地对互斥量进行上锁和解锁。不同的是,Mutex是递归的,这意味着同一个互斥量允许被同一个线程锁定多次;FastMutex是非递归的,这意味着如果同一个线程尝试再次锁定一个已经被锁定的互斥量,将会出现死锁的现象。
2.类图
2.1)Mutex私有继承于MutexImpl,类内包含模板参数为Mutex的ScopedLock类声明。
2.2)FastMutex私有继承于FastMutexImpl,类内包含模板参数为FastMutex的ScopedLock类声明,FastMutexImpl公有继承于MutexImpl。
2.3)MutexImpl类封装了linux互斥锁相关的系统调用。
2.4)ScopedLock模板类的析构和构造函数对传入“锁对象”进行上锁和解锁操作。
3.接口解析
template <class M>
class ScopedLock
/// A class that simplifies thread synchronization
/// with a mutex.
/// The constructor accepts a Mutex (and optionally
/// a timeout value in milliseconds) and locks it.
/// The destructor unlocks the mutex.
{
public:
explicit ScopedLock(M& mutex): _mutex(mutex)
{
_mutex.lock();
}
ScopedLock(M& mutex, long milliseconds): _mutex(mutex)
{
_mutex.lock(milliseconds);
}
~ScopedLock()
{
try
{
_mutex.unlock();
}
catch (...)
{
poco_unexpected();
}
}
private:
M& _mutex;
ScopedLock();
ScopedLock(const ScopedLock&);
ScopedLock& operator = (const ScopedLock&);
};
3.1Mutex
3.1.1构造函数
Mutex::Mutex()
{
}
MutexImpl::MutexImpl()
{
#if defined(POCO_VXWORKS)
/// ... ...
#endif
pthread_mutexattr_t attr;
pthread_mutexattr_init(&attr);
#if defined(PTHREAD_MUTEX_RECURSIVE_NP)
/// ... ...
#elif !defined(POCO_VXWORKS)
pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
#endif
if (pthread_mutex_init(&_mutex, &attr))
{
pthread_mutexattr_destroy(&attr);
throw SystemException("cannot create mutex");
}
pthread_mutexattr_destroy(&attr);
}
Mutex的构造函数略;MutexImpl的构造函数主要完成以下工作:
1)pthread_mutexattr_init()初始化属性对象attr
2)pthread_mutexattr_settype()设定属性对象attr为PTHREAD_MUTEX_RECURSIVE
3)pthread_mutex_init()使用属性attr来初始化互斥锁_mutex
4)pthread_mutexattr_destroy()销毁属性对象attr
3.1.2析构函数
Mutex::~Mutex()
{
}
MutexImpl::~MutexImpl()
{
pthread_mutex_destroy(&_mutex);
}
Mutex的析构函数略;MutexImpl的析构函数主要完成以下工作:
1)pthread_mutex_destroy()销毁互斥锁_mutex
3.1.3lock()函数
inline void Mutex::lock()
{
lockImpl();
}
inline void MutexImpl::lockImpl()
{
if (pthread_mutex_lock(&_mutex))
throw SystemException("cannot lock mutex");
}
MutexImpl的lockImpl函数主要完成以下工作:
1)pthread_mutex_lock()以阻塞方式申请互斥锁_mutex
3.1.4lock(long milliseconds)函数
inline void Mutex::lock(long milliseconds)
{
if (!tryLockImpl(milliseconds))
throw TimeoutException();
}
bool MutexImpl::tryLockImpl(long milliseconds)
{
#if defined(POCO_HAVE_MUTEX_TIMEOUT)
struct timespec abstime;
#if defined(POCO_HAVE_CLOCK_GETTIME)
clock_gettime(CLOCK_REALTIME, &abstime);
abstime.tv_sec += milliseconds / 1000;
abstime.tv_nsec += (milliseconds % 1000)*1000000;
if (abstime.tv_nsec >= 1000000000)
{
abstime.tv_nsec -= 1000000000;
abstime.tv_sec++;
}
#else
/// ... ...
#endif
int rc = pthread_mutex_timedlock(&_mutex, &abstime);
if (rc == 0)
return true;
else if (rc == ETIMEDOUT)
return false;
else
throw SystemException("cannot lock mutex");
#else
/// ... ...
#endif
}
MutexImpl的tryLockImpl(long milliseconds)函数主要完成以下工作:
1)计算等待过期时的绝对时间abstime
2)pthread_mutex_timedlock()以阻塞方式申请互斥锁_mutex,到达超时时间值时返回错误码ETIMEDOUT
3.1.5tryLock()函数
inline bool Mutex::tryLock()
{
return tryLockImpl();
}
inline bool MutexImpl::tryLockImpl()
{
int rc = pthread_mutex_trylock(&_mutex);
if (rc == 0)
return true;
else if (rc == EBUSY)
return false;
else
throw SystemException("cannot lock mutex");
}
MutexImpl的tryLockImpl函数主要完成以下工作:
1)pthread_mutex_trylock()以非阻塞方式申请互斥锁_mutex
3.1.6tryLock(long milliseconds)函数
inline bool Mutex::tryLock(long milliseconds)
{
return tryLockImpl(milliseconds);
}
MutexImpl的tryLockImpl(long milliseconds)函数主要完成以下工作:同3.1.4
3.1.7unlock()函数
inline void Mutex::unlock()
{
unlockImpl();
}
inline void MutexImpl::unlockImpl()
{
if (pthread_mutex_unlock(&_mutex))
throw SystemException("cannot unlock mutex");
}
MutexImpl的unlockImpl函数主要完成以下工作:
1)pthread_mutex_unlock()释放互斥锁_mutex
3.2FastMutex
3.2.1构造函数
FastMutex::FastMutex()
{
}
FastMutexImpl::FastMutexImpl(): MutexImpl(true)
{
}
MutexImpl::MutexImpl(bool fast)
{
#if defined(POCO_VXWORKS)
/// ... ...
#endif
pthread_mutexattr_t attr;
pthread_mutexattr_init(&attr);
#if defined(PTHREAD_MUTEX_RECURSIVE_NP)
/// ... ...
#elif !defined(POCO_VXWORKS)
pthread_mutexattr_settype(&attr, fast ? PTHREAD_MUTEX_NORMAL : PTHREAD_MUTEX_RECURSIVE);
#endif
if (pthread_mutex_init(&_mutex, &attr))
{
pthread_mutexattr_destroy(&attr);
throw SystemException("cannot create mutex");
}
pthread_mutexattr_destroy(&attr);
}
FastMutex和FastMutexImpl的构造函数略,MutexImpl的构造函数主要完成以下工作:
1)pthread_mutexattr_init()初始化属性对象attr
2)pthread_mutexattr_settype()设定属性对象attr为PTHREAD_MUTEX_NORMAL(Mutex与FastMutex最主要区别的原因)
3)pthread_mutex_init()使用属性attr来初始化互斥锁_mutex
4)pthread_mutexattr_destroy()销毁属性对象attr
3.2.2析构函数
FastMutex::~FastMutex()
{
}
FastMutexImpl::~FastMutexImpl()
{
}
MutexImpl::~MutexImpl()
{
pthread_mutex_destroy(&_mutex);
}
FastMutex和FastMutexImpl的析构函数略,MutexImpl的析构函数主要完成以下工作:
1)pthread_mutex_destroy()销毁互斥锁_mutex
3.2.3lock()函数
inline void FastMutex::lock()
{
lockImpl();
}
inline void MutexImpl::lockImpl()
{
if (pthread_mutex_lock(&_mutex))
throw SystemException("cannot lock mutex");
}
MutexImpl的lockImpl函数主要完成以下工作:
1)pthread_mutex_lock()以阻塞方式申请互斥锁_mutex
3.2.4lock(long milliseconds)函数
inline void FastMutex::lock(long milliseconds)
{
if (!tryLockImpl(milliseconds))
throw TimeoutException();
}
bool MutexImpl::tryLockImpl(long milliseconds)
{
#if defined(POCO_HAVE_MUTEX_TIMEOUT)
struct timespec abstime;
#if defined(POCO_HAVE_CLOCK_GETTIME)
clock_gettime(CLOCK_REALTIME, &abstime);
abstime.tv_sec += milliseconds / 1000;
abstime.tv_nsec += (milliseconds % 1000)*1000000;
if (abstime.tv_nsec >= 1000000000)
{
abstime.tv_nsec -= 1000000000;
abstime.tv_sec++;
}
#else
/// ... ...
#endif
int rc = pthread_mutex_timedlock(&_mutex, &abstime);
if (rc == 0)
return true;
else if (rc == ETIMEDOUT)
return false;
else
throw SystemException("cannot lock mutex");
#else
/// ... ...
#endif
}
MutexImpl的tryLockImpl(long milliseconds)函数主要完成以下工作:
1)计算等待过期时的绝对时间abstime
2)pthread_mutex_timedlock()以阻塞方式申请互斥锁_mutex,到达超时时间值时返回错误码ETIMEDOUT
3.2.5tryLock()函数
inline bool FastMutex::tryLock()
{
return tryLockImpl();
}
inline bool MutexImpl::tryLockImpl()
{
int rc = pthread_mutex_trylock(&_mutex);
if (rc == 0)
return true;
else if (rc == EBUSY)
return false;
else
throw SystemException("cannot lock mutex");
}
MutexImpl的tryLockImpl函数主要完成以下工作:
1)pthread_mutex_trylock()以非阻塞方式申请互斥锁_mutex
3.2.6tryLock(long milliseconds)函数
inline bool FastMutex::tryLock(long milliseconds)
{
return tryLockImpl(milliseconds);
}
MutexImpl的tryLockImpl(long milliseconds)函数主要完成以下工作:同3.2.4
3.2.7unlock()函数
inline void FastMutex::unlock()
{
unlockImpl();
}
inline void MutexImpl::unlockImpl()
{
if (pthread_mutex_unlock(&_mutex))
throw SystemException("cannot unlock mutex");
}
MutexImpl的unlockImpl函数主要完成以下工作:
1)pthread_mutex_unlock()释放互斥锁_mutex

本文详细剖析了C++ Poco库中Mutex和FastMutex的实现,包括构造、析构、lock、tryLock及unlock等关键函数。Mutex是递归互斥锁,允许同一线程多次锁定,而FastMutex是非递归的,重复锁定会导致死锁。两者都使用了pthread库的相关系统调用来实现锁机制。
7025

被折叠的 条评论
为什么被折叠?



