1

所以我想我了解信号和等待的源代码(等待是锁),但我不确定如何实现尝试锁。这是我等待的代码:

//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);
        }
}
4

2 回答 2

4

一个常规的自旋锁是这样实现的(伪 C-codish):

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!
}

比较和交换

于 2012-10-14T03:41:46.980 回答
0

我正在寻找一个非自旋锁trylock。我已经想好该怎么做了。如果它是一个计数信号量,那么如果计数为正,我会递减并消耗资源。如果它是零或更少,我什么也不做,只返回一个错误代码。我不会减少计数或消耗资源。然后程序能够继续超过那个点。如果它是二进制信号量,我会在资源可用时使用它。然后我将二进制信号量的值更改为已消耗。如果它不可用,那么我返回一个错误代码。

于 2012-10-15T18:55:05.530 回答