1

したがって、シグナルと待機(待機はロック)のソースコードは理解していると思いますが、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);
        }
}
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

非スピンロックトライロックを探していました。私は何をすべきかを理解しました。カウントセマフォの場合、カウントが正の場合はデクリメントし、リソースを消費します。ゼロ以下の場合は、エラーコードを返すだけです。カウントを減らしたり、リソースを消費したりしません。その後、プログラムはそのポイントを超えて続行できます。バイナリセマフォの場合、リソースが利用可能であれば消費します。次に、バイナリセマフォの値をconsumedに変更します。利用できない場合は、エラーコードを返します。

于 2012-10-15T18:55:05.530 に答える