本文主要是介绍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;
}
这篇关于vxworks下可递归互斥锁的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!