nlib
misc/threading/semaphore/semaphore.cpp

セマフォのサンプルです。 セマフォは何らかの限られた数のリソースを複数のスレッドで利用するための仕組みです。

メインスレッドでは、以下の処理を行います。

  1. nn::nlib::threading::Semaphore::Init()関数でセマフォカウントの初期値を0(誰もセマフォを獲得できない),最大値を2に設定します。
  2. kNumThread個のスレッドを立ち上げます。
  3. セマフォを解放してセマフォカウントを2にすることで、最大2つのスレッドがセマフォを取得できるようにします。

その他のスレッドでは、SemaphoreDemoFunc()関数で、以下の処理を行います。

  1. nn::nlib::threading::Semaphore::Acquire()関数で、セマフォが獲得できるまで待ちます。
  2. セマフォが獲得(セマフォカウントが-1される)できたら、1 msecずつ2回スリープします。同時に2スレッドまでがこの処理を実行できます。
  3. nn::nlib::threading::Semaphore::Release()関数で、セマフォを解放(セマフォカウントが+1される)します。
/*--------------------------------------------------------------------------------*
Project: CrossRoad
Copyright (C)Nintendo All rights reserved.
These coded instructions, statements, and computer programs contain proprietary
information of Nintendo and/or its licensed developers and are protected by
national and international copyright laws. They may not be disclosed to third
parties or copied or duplicated in any form, in whole or in part, without the
prior written consent of Nintendo.
The content herein is highly confidential and should be handled accordingly.
*--------------------------------------------------------------------------------*/
using ::nlib_ns::threading::Semaphore;
using ::nlib_ns::threading::Thread;
const int kNumThread = 10;
Thread g_th[kNumThread];
Semaphore g_semaphore;
void SemaphoreDemoFunc(int threadNum) {
nlib_printf(" Thread %d, Trying wait semaphore\n", threadNum);
g_semaphore.Acquire();
nlib_printf(" Thread %d, Success get semaphore\n", threadNum);
for (int i = 0; i < 2; ++i) {
nlib_printf(" Thread %d, doing jobs using limited resource\n", threadNum);
}
nlib_printf(" Thread %d, Release semaphore\n", threadNum);
g_semaphore.Release(NULL);
}
bool SemaphoreDemo() {
nlib_printf("-- Semaphore Demo --\n");
// initializes Semaphore
e = g_semaphore.Init(0);
if (e != 0) return false;
int i;
for (i = 0; i < kNumThread; ++i) {
e = g_th[i].Start(SemaphoreDemoFunc, i);
NLIB_ASSERT_NOERR(e);
}
// kNumThread threads share 2 resources
nlib_printf("Main Thread: Release semaphores\n");
e = g_semaphore.Release(2, NULL);
NLIB_ASSERT_NOERR(e);
for (i = 0; i < kNumThread; ++i) {
e = g_th[i].Join();
NLIB_ASSERT_NOERR(e);
}
return true;
}
static bool SampleMain(int, char**) { return SemaphoreDemo(); }
NLIB_MAINFUNC