造轮子之线程锁的封装

线程锁的封装

线程锁的基本操作:

1. 创建锁 int pthread_mutex_init(pthread_mutex_t*mutex, const pthread_mutexattr_t * attr);
    attr:创建锁的属性。一般默认为NULL,分为以下几个属性:
        * PTHREAD_MUTEX_TIMED_NP,这是缺省值,也就是普通锁。当一个线程加锁以后,其余请求锁的线程将形成一个等待队列,并在解锁后按优先级获得锁。这种锁策略保证了资源分配的公平性;
        * PTHREAD_MUTEX_RECURSIVE_NP,嵌套锁,允许同一个线程对同一个锁成功获得多次,并通过多次unlock解锁。如果是不同线程请求,则在加锁线程解锁时重新竞争;
        * PTHREAD_MUTEX_ERRORCHECK_NP,检错锁,如果同一个线程请求同一个锁,则返回EDEADLK,否则与PTHREAD_MUTEX_TIMED_NP类型动作相同。这样就保证当不允许多次加锁时不会出现最简单情况下的死锁;
        * PTHREAD_MUTEX_ADAPTIVE_NP,适应锁,动作最简单的锁类型,仅等待解锁后重新竞争;
2. 加锁 int pthread_mutex_lock(pthread_mutex_t*mutex);
3. 解锁 int pthread_mutex_unlock(pthread_mutex_t *mutex);
4. 尝试锁 int pthread_mutex_trylock(pthread_mutex_t *mutex); //锁被占用返回EBUSY,而非等待
5. 锁销毁 int pthread_mutexattr_destroy (pthread_mutex_t *mutex);

线程锁的封装

线程锁异常
struct YR_ThreadMutex_Exception : public YR_Lock_Exception
{
    YR_ThreadMutex_Exception(const string &buffer) : YR_Lock_Exception(buffer){};
    YR_ThreadMutex_Exception(const string &buffer, int err) : YR_Lock_Exception(buffer, err){};
    ~YR_ThreadMutex_Exception() throw() {};
};
线程锁的定义
class YR_ThreadMutex
{
public:
	YR_ThreadMutex();
    virtual ~YR_ThreadMutex();
    //加锁
    void lock() const;
    //解锁
    void unlock() const;
    //尝试锁
    bool tryLock() const;
protected:
    mutable pthread_mutex_t _mutex;			//创建线程锁
};
实现

锁的初始化可以放在构造函数里,这里分为四步来初始化线程锁_mutex

YR_ThreadMutex::YR_ThreadMutex()
{
	int rc;
    pthread_mutexattr_t attr;					//1. 创建线程锁属性对象
    rc = pthread_mutexattr_init(&attr);			//初始化锁属性对象
    assert(rc == 0);
    
    //2. 将锁属性中的锁类型设为检错锁
    rc = pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_ERRORCHECK);
    assert(rc == 0);
    
    //3. 初始化锁对象
    rc = pthread_mutex_init(&_mutex, &attr);
    assert(rc == 0);
    
    //4. 销毁锁属性对象
    rc = pthread_mutexattr_destroy(&attr);
    assert(rc == 0);
    
    //如果操作不成功,则抛出异常
    if(rc != 0)
    {
        throw TC_ThreadMutex_Exception("[TC_ThreadMutex::TC_ThreadMutex] pthread_mutexattr_init error", rc);
    }
}

线程锁在析构函数中销毁:

YR_ThreadMutex::~YR_ThreadMutex()
{
    int rc = 0;
    rc = pthread_mutex_destroy(&_mutex);
    if(rc != 0)
    {
        cerr << "[YR_ThreadMutex::~YR_ThreadMutex] pthread_mutex_destroy error:" << string(strerror(rc)) << endl;
    }
}
加锁
void YR_ThreadMutex::lock() const
{
    int rc = pthread_mutex_lock(&_mutex);
    if(rc != 0)
    {
        if(rc == EDEADLK)		//如果当前线程已经拥有线程锁
        {
            throw YR_ThreadMutex_Exception("[YR_ThreadMutex::lock] pthread_mutex_lock dead lock error", rc);
        }
        else
        {
            throw YR_ThreadMutex_Exception("[YR_ThreadMutex::lock] pthread_mutex_lock error", rc);
        }
    }
}
解锁
void YR_ThreadMutex::unlock() const
{
    int rc = pthread_mutex_unlock(&_mutex);
    if(rc != 0)
    {
        throw YR_ThreadMutex_Exception("[YR_ThreadMutex::unlock] pthread_mutex_unlock error", rc);
    }
}
尝试锁
bool YR_ThreadMutex::tryLock() const
{
    int rc = pthread_mutex_trylock(&_mutex);
    if(rc != 0 && rc != EBUSY)		//如果所占用则返回EBUSY
    {
        if(rc == EDEADLK)			//如果当前线程已经拥有线程锁
        {
            throw YR_ThreadMutex_Exception("[YR_ThreadMutex::tryLock] pthread_mutex_trylock dead lock error", rc);
        }
        else
        {
            throw YR_ThreadMutex_Exception("[YR_ThreadMutex::tryLock] pthread_mutex_trylock error", rc);
        }
    }
    return (rc == 0);
}

嵌套锁的封装

嵌套锁的定义
class YR_ThreadRecMutex
{
public:
    /**
    * @brief 构造函数
    */
    YR_ThreadRecMutex();

    /**
    * @brief 析够函数
    */
    virtual ~YR_ThreadRecMutex();

    /**
    * @brief 锁, 调用pthread_mutex_lock. 
    *  
    * return : 返回pthread_mutex_lock的返回值
    */
    int lock() const;

    /**
    * @brief 解锁, pthread_mutex_unlock. 
    *  
    * return : 返回pthread_mutex_lock的返回值
    */
    int unlock() const;

    /**
    * @brief 尝试锁, 失败抛出异常. 
    *  
    * return : true, 成功锁; false 其他线程已经锁了
    */
    bool tryLock() const;
    /**
     * @brief 加锁后调用unlock是否会解锁, 给TC_Monitor使用的
     * 
     * @return bool
     */
    bool willUnlock() const;
protected:
    /**
     * @brief 友元类
     */
    friend class TC_ThreadCond;

    /**
     * @brief 计数
     */
    int count() const;

    /**
     * @brief 计数
     */
    void count(int c) const;
private:
    /**
    锁对象
    */
    mutable pthread_mutex_t _mutex;
    mutable int _count;
};
实现
YR_ThreadRecMutex::YR_ThreadRecMutex()
: _count(0)
{
    int rc;

    pthread_mutexattr_t attr;
    //1. 线程属性的初始化
    rc = pthread_mutexattr_init(&attr);
    if(rc != 0)
    {
        throw YR_ThreadMutex_Exception("[YR_ThreadRecMutex::YR_ThreadRecMutex] pthread_mutexattr_init error", rc);
    }
    //2. 设置线程锁类型,PTHREAD_MUTEX_RECURSIVE为嵌套锁
    rc = pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
    if(rc != 0)
    {
        throw YR_ThreadMutex_Exception("[YR_ThreadRecMutex::YR_ThreadRecMutex] pthread_mutexattr_settype error", rc);
    }

    //3. 初始化线程
    rc = pthread_mutex_init(&_mutex, &attr);
    if(rc != 0)
    {
        throw YR_ThreadMutex_Exception("[YR_ThreadRecMutex::YR_ThreadRecMutex] pthread_mutex_init error", rc);
    }

    //4. 销毁线程属性对象
    rc = pthread_mutexattr_destroy(&attr);
    if(rc != 0)
    {
        throw YR_ThreadMutex_Exception("[YR_ThreadRecMutex::YR_ThreadRecMutex] pthread_mutexattr_destroy error", rc);
    }
}

YR_ThreadRecMutex::~YR_ThreadRecMutex()
{
    while (_count)
    {
        unlock();
    }

    int rc = 0;
    rc = pthread_mutex_destroy(&_mutex);			//销毁线程
    if(rc != 0)
    {
        cerr << "[YR_ThreadRecMutex::~YR_ThreadRecMutex] pthread_mutex_destroy error:" << string(strerror(rc)) << endl;
    }
}
加锁
int YR_ThreadRecMutex::lock() const
{
	int rc = pthread_mutex_lock(&_mutex);
    if(rc != 0)
    {
        //嵌套锁不用判断EDEADLK
        throw YR_ThreadMutex_Exception("[YR_ThreadRecMutex::lock] pthread_mutex_lock error",rc);
    }
    
    //只是计数加1,pthread_mutex_unlock避免锁叠加
    if(++_count > 1)
    {
        rc = pthread_mutex_unlock(&_mutex);		
        assert(rc == 0);
    }
    return rc;
}
解锁
int YR_ThreadRecMutex::unlock() const
{
    //当计数只有1的时候进行解锁操作,大于1的情况只是计数减一即可
    if(--_count == 0)
    {
        int rc = 0;
        rc = pthread_mutex_unlock(&_mutex);
        return rc;
    }
    return 0;
}
尝试锁
bool YR_ThreadRecMutex::tryLock() const
{
    int rc = pthread_mutex_trylock(&_mutex);
    if(rc != 0 )
    {
        if(rc != EBUSY)
        {
            throw YR_ThreadMutex_Exception("[YR_ThreadRecMutex::tryLock] pthread_mutex_trylock error", rc);
        }
    }
    else if(++_count > 1)
    {
        rc = pthread_mutex_unlock(&_mutex);
        if(rc != 0)
        {
            throw YR_ThreadMutex_Exception("[YR_ThreadRecMutex::tryLock] pthread_mutex_unlock error", rc);
        }
    }
    return (rc == 0);
}

计数
int YR_ThreadRecMutex::count() const
{
    int c   = _count;
    _count  = 0;
    return c;
}

void YR_ThreadRecMutex::count(int c) const
{
    _count = c;
}

unlock()之后是否会解锁
bool YR_ThreadRecMutex::willUnlock() const
{
    return _count == 1;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值