[ここで使用される用語は、POSIXスレッドに固有の場合があります]
FIFOミューテックスを使用してこの問題を解決することも可能です。
使用する場所:
2つのスレッドT1とT2がクリティカルセクションを実行しようとしているとします。どちらも、この重要なセクションの外で行うことはあまりなく、十分な時間ロックを保持します。そのため、T1はT2をロック、実行、およびロック解除し、ウェイクアップのために信号を送ることができます。ただし、T2がウェイクアップしてロックを取得する前に、T1はロックを再取得して実行します。このように、T2は実際にロックを取得するまで待機するか、そうでない場合があります。
仕組み/実装方法:
ロックするミューテックスがあります。各スレッドのスレッド固有データ(TSD)を、スレッドIDとセマフォを含むノードに初期化します。また、所有(TRUEまたはFALSEまたは-1)、所有者(所有者スレッドID)の2つの変数があります。さらに、ウェイターキューと、ウェイターキューの最後のノードを指すポインターwaiterLastを保持します。
ロック操作:
node = get_thread_specific_data(node_key);
lock(mutex);
if(!owned)
{
owned = true;
owner = self;
return success;
}
node->next = nullptr;
if(waiters_queue == null) waiters_queue = node;
else waiters_last->next = node;
waiters_last = node;
unlock(mutex);
sem_wait(node->semaphore);
lock(mutex);
if(owned != -1) abort();
owned = true;
owner = self;
waiters_queue = waiters_queue->next;
unlock(mutex);
ロック解除操作:
lock(mutex);
owner = null;
if(waiters_queue == null)
{
owned = false;
return success;
}
owned = -1;
sem_post(waiters_queue->semaphore);
unlock(mutex);