所以我认为我理解信号和等待的源代码(等待是锁定),但我不确定如何实现try锁。 这是我的等待代码:
//if s->type is zero it is a binary semaphore type
if (s->type == 0)
{
// binary semaphore
// if state is zero, then block task
if (s->state == 0)
{
// block task
// ?? move task from ready queue to blocked queue
//reschedule the tasks
return 1;
}
// state is non-zero (semaphore already signaled)
s->state = 0; // reset state, and don't block
return 0;
}
else
{
// counting semaphore
s->state--;
// ?? implement counting semaphore
if (s->state < 0)
{
}
}
到目前为止,这是我尝试锁定的方法:
if (s->type == 0)
{
// binary semaphore
// if state is zero, then block task
if (s->state == 0)
{
tcb[curTask].event = s; // block task
tcb[curTask].state = S_BLOCKED;
removeNode(tcb[curTask].priority, READY_QUEUE, curTask);
enqueue(tcb[curTask].priority, curTask, BLOCKED_QUEUE);
return 1;
}
// state is non-zero (semaphore already signaled)
s->state = 1; // reset state, and don't block
return 0;
}
else
{
s->state--;
if (s->state >= 0)
{
s->state++;
}
else
{
tcb[curTask].event = s;
tcb[curTask].state = S_BLOCKED;
removeNode(tcb[curTask].priority, READY_QUEUE, curTask);
enqueue(tcb[curTask].priority, curTask, BLOCKED_QUEUE);
}
}
答案 0 :(得分:4)
常规旋转锁是这样实现的(伪C编码):
void lock(locktype_t* LockVariable)
{
while (CompareAndSwap(LockVariable,
STATE_UNLOCKED /* state to wait for */,
STATE_LOCKED /* new state to try to set */) !=
STATE_UNLOCKED /* expected state at the beginning of CAS() */)
{
// spin here, doing nothing useful, waiting for *LockVariable to
// first become STATE_UNLOCKED (CAS() returns its last value), after
// which we will set it to STATE_LOCKED (CAS() will do that atomically)
}
}
void unlock(locktype_t* LockVariable)
{
*LockVariable = STATE_UNLOCKED;
}
如果无限期旋转并等待锁首次解锁是不可取的,我们会使用上述类似的无环变体:
int tryToLock(locktype_t* LockVariable)
{
if (CompareAndSwap(LockVariable,
STATE_UNLOCKED /* state to wait for */,
STATE_LOCKED /* new state to try to set */) !=
STATE_UNLOCKED /* expected state at the beginning of CAS() */)
{
return 0; // the lock is still held by someone else, bail out
}
return 1; // the lock is now held by us, hurray!
}
答案 1 :(得分:0)
我正在寻找一个非旋转锁定的trylock。 我已经弄明白该怎么做了。如果它是一个计数信号量,那么如果计数是正数并且我消耗了资源,那么我会减少。如果它为零或更少,我什么也不做,只返回错误代码。我不减少计数或消耗资源。然后该程序能够继续超过该点。如果它是二进制信号量,如果资源可用,我会使用它。然后我将二进制信号量的值更改为已使用。如果它不可用,则返回错误代码。