nlib
misc/threading/semaphore/semaphore.cpp

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

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

  1. nn::nlib::threading::Semaphore::Init()関数でセマフォカウントの初期値を0(誰もセマフォを獲得できない),最大値を2に設定します。
  2. NUM_THREAD個のスレッドを立ち上げます。
  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)2012-2016 Nintendo. All rights reserved.
These coded instructions, statements, and computer programs contain
proprietary information of Nintendo of America Inc. and/or Nintendo
Company Ltd., and are protected by Federal copyright law. 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.
*---------------------------------------------------------------------------*/
using ::nlib_ns::threading::Semaphore;
using ::nlib_ns::threading::Thread;
const int NUM_THREAD = 10;
Thread g_Th[NUM_THREAD];
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 < NUM_THREAD; ++i) {
e = g_Th[i].Start(SemaphoreDemoFunc, i);
NLIB_ASSERT_NOERR(e);
}
// NUM_THREAD 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 < NUM_THREAD; ++i) {
e = g_Th[i].Join();
NLIB_ASSERT_NOERR(e);
}
return true;
}
static bool SampleMain(int, char**) { return SemaphoreDemo(); }
NLIB_MAINFUNC