c++ poco Mutex相关 源码剖析

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

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值