2019-12-24 21:21:33 +08:00
|
|
|
|
#ifndef HGL_THREAD_SEM_LOCK_INCLUDE
|
2019-08-19 19:19:58 +08:00
|
|
|
|
#define HGL_THREAD_SEM_LOCK_INCLUDE
|
|
|
|
|
|
|
|
|
|
#include<hgl/thread/Semaphore.h>
|
|
|
|
|
#include<hgl/thread/ThreadMutex.h>
|
|
|
|
|
#include<hgl/thread/RWLock.h>
|
|
|
|
|
namespace hgl
|
|
|
|
|
{
|
|
|
|
|
template<typename T,typename L> class SemLockTemplate
|
|
|
|
|
{
|
|
|
|
|
protected:
|
|
|
|
|
|
|
|
|
|
T data;
|
|
|
|
|
|
|
|
|
|
L lock;
|
|
|
|
|
Semaphore sem;
|
|
|
|
|
|
|
|
|
|
public:
|
|
|
|
|
|
|
|
|
|
SemLockTemplate(){}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 本类构造函数
|
|
|
|
|
* @param d 数据
|
|
|
|
|
* @param sem_count 最大信号数量(默认0表示不限制)
|
|
|
|
|
*/
|
|
|
|
|
SemLockTemplate(T &d,int sem_count=0):sem(sem_count)
|
|
|
|
|
{
|
|
|
|
|
data=d;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public: //数据相关
|
|
|
|
|
|
|
|
|
|
void operator = (T &d){data=d;}
|
|
|
|
|
T *operator->(){return &data;}
|
|
|
|
|
|
|
|
|
|
public: //信号相关
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 释放信号
|
|
|
|
|
* @param n 释放的信号数量
|
|
|
|
|
* @return 是否成功
|
|
|
|
|
*/
|
|
|
|
|
bool Post(int n=1)
|
|
|
|
|
{
|
|
|
|
|
if(n<=0)return(false);
|
|
|
|
|
return sem.Post(n);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool TryAcquire(){return sem.TryAcquire();} ///<尝试获取一个信号
|
|
|
|
|
/**
|
|
|
|
|
* 获取一个信号
|
|
|
|
|
* @param time_out 超时时间
|
|
|
|
|
* @return 是否成功
|
|
|
|
|
*/
|
2019-12-24 21:21:33 +08:00
|
|
|
|
bool Acquire(double time_out=0.0f){return sem.Acquire(time_out);}
|
2019-08-19 19:19:58 +08:00
|
|
|
|
};//template<typename T,typename L> class SemLockTemplate
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 信号线程排斥
|
|
|
|
|
*/
|
|
|
|
|
template<typename T> class SemThreadMutex:public SemLockTemplate<T,ThreadMutex>
|
|
|
|
|
{
|
|
|
|
|
public:
|
|
|
|
|
|
|
|
|
|
using SemLockTemplate<T,ThreadMutex>::SemLockTemplate;
|
|
|
|
|
|
|
|
|
|
public: //线程排斥相关
|
|
|
|
|
|
|
|
|
|
void Lock(){this->lock.Lock();} ///<取得的控制权(如果对象处于排斥状态,则等待)
|
|
|
|
|
bool TryLock(){return this->lock.TryLock();} ///<尝试取得控制权
|
|
|
|
|
bool WaitLock(double time_out=0){return this->lock.WaitLock();} ///<等待并取得控制权
|
|
|
|
|
void Unlock(){this->lock.Unlock();} ///<放弃控制权
|
|
|
|
|
|
|
|
|
|
public: //综合应用相关
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 在指定时间内如果成功捕获到信号则锁定
|
|
|
|
|
* @param time_out 最长等待时间
|
|
|
|
|
* @return 是否锁定了
|
|
|
|
|
*/
|
|
|
|
|
bool WaitSemLock(double time_out)
|
|
|
|
|
{
|
|
|
|
|
if(!this->sem.Acquire(time_out))
|
|
|
|
|
return(false);
|
|
|
|
|
|
|
|
|
|
this->lock.Lock();
|
|
|
|
|
return(true);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 尝试捕获一个信号,如果成功则锁定
|
|
|
|
|
* @return 是否锁定了
|
|
|
|
|
*/
|
|
|
|
|
bool TrySemLock()
|
|
|
|
|
{
|
|
|
|
|
if(!this->sem.TryAcquire())
|
|
|
|
|
return(false);
|
|
|
|
|
|
|
|
|
|
this->lock.Lock();
|
|
|
|
|
return(true);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 锁定
|
|
|
|
|
* @param try_lock 是否是尝试锁定
|
|
|
|
|
* @param time_out 如果不是尝试锁定,则等待锁定的超时时间
|
|
|
|
|
*/
|
|
|
|
|
bool SemLock(bool try_lock,double time_out)
|
|
|
|
|
{
|
|
|
|
|
if(try_lock)
|
|
|
|
|
{
|
|
|
|
|
if(!this->sem.TryAcquire())
|
|
|
|
|
return(false);
|
|
|
|
|
}
|
|
|
|
|
else //当前没人,那就慢慢等吧
|
|
|
|
|
{
|
|
|
|
|
if(!this->sem.Acquire(time_out))
|
|
|
|
|
return(false);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
this->lock.Lock();
|
|
|
|
|
return(true);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 解锁并释放信号
|
|
|
|
|
* @param n 释放的信号数量
|
|
|
|
|
*/
|
|
|
|
|
void SemUnlock(int n=1)
|
|
|
|
|
{
|
|
|
|
|
this->lock.Unlock();
|
|
|
|
|
|
|
|
|
|
if(n>0)
|
|
|
|
|
this->sem.Post(n);
|
|
|
|
|
}
|
|
|
|
|
};//template<typename T> class SemThreadMutex
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 信号读写锁
|
|
|
|
|
*/
|
|
|
|
|
template<typename T> class SemRWLock:public SemLockTemplate<T,RWLock>
|
|
|
|
|
{
|
|
|
|
|
public:
|
|
|
|
|
|
|
|
|
|
using SemLockTemplate<T,RWLock>::SemLockTemplate;
|
|
|
|
|
|
|
|
|
|
public: //读写锁相关
|
|
|
|
|
|
|
|
|
|
HGL_RWLOCK(this->lock);
|
|
|
|
|
|
|
|
|
|
public: //综合应用相关
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 在指定时间内如果成功捕获到信号则共享锁定
|
|
|
|
|
* @param time_out 最长等待时间
|
|
|
|
|
* @return 是否锁定了
|
|
|
|
|
*/
|
|
|
|
|
bool WaitSemReadLock(double time_out)
|
|
|
|
|
{
|
|
|
|
|
if(!this->sem.Acquire(time_out))
|
|
|
|
|
return(false);
|
|
|
|
|
|
|
|
|
|
this->lock.ReadLock();
|
|
|
|
|
return(true);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 在指定时间内如果成功捕获到信号则独占锁定
|
|
|
|
|
* @param time_out 最长等待时间
|
|
|
|
|
* @return 是否锁定了
|
|
|
|
|
*/
|
|
|
|
|
bool WaitSemWriteLock(double time_out)
|
|
|
|
|
{
|
|
|
|
|
if(!this->sem.Acquire(time_out))
|
|
|
|
|
return(false);
|
|
|
|
|
|
|
|
|
|
this->lock.WriteLock();
|
|
|
|
|
return(true);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 尝试捕获一个信号,如果成功则共享锁定
|
|
|
|
|
* @return 是否锁定了
|
|
|
|
|
*/
|
|
|
|
|
bool TrySemReadLock()
|
|
|
|
|
{
|
|
|
|
|
if(!this->sem.TryAcquire())
|
|
|
|
|
return(false);
|
|
|
|
|
|
|
|
|
|
this->lock.ReadLock();
|
|
|
|
|
return(true);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 尝试捕获一个信号,如果成功则独占锁定
|
|
|
|
|
* @return 是否锁定了
|
|
|
|
|
*/
|
|
|
|
|
bool TrySemWriteLock()
|
|
|
|
|
{
|
|
|
|
|
if(!this->sem.TryAcquire())
|
|
|
|
|
return(false);
|
|
|
|
|
|
|
|
|
|
this->lock.WriteLock();
|
|
|
|
|
return(true);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 解除共享锁并释放信号
|
|
|
|
|
* @param n 释放的信号数量
|
|
|
|
|
*/
|
|
|
|
|
void SemReadUnlock(int n=1)
|
|
|
|
|
{
|
|
|
|
|
this->lock.ReadUnlock();
|
|
|
|
|
|
|
|
|
|
if(n>0)
|
|
|
|
|
this->sem.Post(n);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 解除独占锁并释放信号
|
|
|
|
|
* @param n 释放的信号数量
|
|
|
|
|
*/
|
|
|
|
|
void SemWriteUnlock(int n=1)
|
|
|
|
|
{
|
|
|
|
|
this->lock.WriteUnlock();
|
|
|
|
|
|
|
|
|
|
if(n>0)
|
|
|
|
|
this->sem.Post(n);
|
|
|
|
|
}
|
|
|
|
|
};//template<typename T> class SemRWLock
|
|
|
|
|
}//namespace hgl
|
|
|
|
|
#endif//HGL_THREAD_SEM_LOCK_INCLUDE
|