vxworks下可递归互斥锁

windows及linux下的互斥锁均可实现递归功能,vxworks下的信号量可实现简单的非递归互斥锁,但很多多线程编程中,往往会出现函数A加锁后紧接着调用函数B,在函数B中再次加锁的需求。下面简单介绍下基于信号量的vxworks可递归互斥锁的实现方法:

       记录互斥线程id、线程递归次数。加锁时判断递归次数,如果递归次数大于0且递归线程id为本线程,则仅增加递归次数,否则可能是两个情况:未被加锁,或其他线程处于加锁中,才semTake信号量,成功后记录互斥线程id,增加递归次数。

       解锁过程则可首先递归次数是否大于0,且递归线程id是否为本线程,仅当以上条件成立,才减少递归次数,同时判断递归次数为0时才semGive,并重置互斥线程id。以上方法还可以防止解锁其他线程加的锁。

代码如下:

typedef struct ST_MUTEX_SEM
{
SEM_ID semId;
int taskId;
int refCount;
}ST_MUTEX_SEM;


ST_RET gs_mutex_create (ST_MUTEX_SEM *ms)
{
ms->semId = semBCreate(SEM_Q_FIFO,SEM_EMPTY);
ms->taskId = 0;
ms->refCount = 0;


semGive(ms->semId);
return SD_SUCCESS;
}




ST_RET gs_mutex_get_tm (ST_MUTEX_SEM *ms, ST_LONG timeout)
{
int taskId = taskIdSelf();
if (!gs_already_inited) /* Make sure gs is initialized. */
   gs_init ();

if(ms->refCount > 0
&& taskId == ms->taskId)
{
++ms->refCount;
return SD_SUCCESS;
}
else
{
/*1.refCount <= 0 
*2.refCount >0,semTake for timeout until refCount=0
**/
if(OK != semTake(ms->semId, timeout))
{
return SD_FAILURE;
}

++ms->refCount;
ms->taskId = taskId;
return SD_SUCCESS;
}
}


ST_RET gs_mutex_free (ST_MUTEX_SEM *ms)
{
int taskId = taskIdSelf();
/*xlx@ user can only free mutex in the same thread*/
if(ms->refCount > 0
&& ms->taskId == taskId)
{
--ms->refCount;
if(ms->refCount == 0)
{
ms->taskId = 0;
semGive(ms->semId);
}
}

return SD_SUCCESS;
}


ST_RET  gs_mutex_destroy (ST_MUTEX_SEM *ms)
{
semDelete(ms->semId);
return SD_SUCCESS;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值