セマフォのサンプルです。 セマフォは何らかの限られた数のリソースを複数のスレッドで利用するための仕組みです。
メインスレッドでは、以下の処理を行います。
-
nn::nlib::threading::Semaphore::Init()
関数でセマフォカウントの初期値を0(誰もセマフォを獲得できない),最大値を2に設定します。
-
NUM_THREAD
個のスレッドを立ち上げます。
-
セマフォを解放してセマフォカウントを2にすることで、最大2つのスレッドがセマフォを取得できるようにします。
その他のスレッドでは、SemaphoreDemoFunc()
関数で、以下の処理を行います。
-
nn::nlib::threading::Semaphore::Acquire()
関数で、セマフォが獲得できるまで待ちます。
-
セマフォが獲得(セマフォカウントが-1される)できたら、1 msecずつ2回スリープします。同時に2スレッドまでがこの処理を実行できます。
-
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() {
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);
}
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