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される)します。
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