boostのcondition variable(条件変数)

Linuxだと pthread_cond_wait() つまり POSIX系、 Windows だと WaitForSingleObject() つまり Win32APIと、スレッドまわりのAPIはOSによって使い分ける必要があります。これは面倒くさい!!そういう場合は boost の boost::thread 一派が便利です。

たとえば、定番の生産者消費者モデルを boost で実装すると、こんな感じ。

#include <iostream>
#include <boost/thread/thread.hpp>
#include <boost/thread/condition.hpp>

using namespace std;

static boost::mutex mutex;
static boost::condition cond;
int num=0;

static void producer()
{
     int loop=10;
     while (loop-->0) 
     {
	  {
	       boost::mutex::scoped_lock lock(mutex);
	       cout << "push" << endl;
	       num = num + 1;

	       // 待機中の consumer() を起こす
	       cond.notify_one();
	  }


	  // 1秒 スレッドを休眠させる
	  boost::xtime xt;
	  boost::xtime_get(&xt, boost::TIME_UTC);
	  xt.sec+= 1;
	  boost::thread::sleep(xt);
     }
}

static void consumer()
{
     int loop=10;
     while (loop-->0) 
     {
	  // グローバル変数 num の値が 1以上になるまで待機
	  boost::mutex::scoped_lock lock(mutex);
	  while (num==0) 
	  {
	       cond.wait(lock);
	  }

	  num = num - 1;
	  cout << "pop" << endl;
     }
}

int main() 
{
   boost::thread th0(producer);
   boost::thread th1(consumer); 

   th0.join();
   th1.join();

   return 0;
}

ただしコンパイルするためには、boostのライブラリをリンクする必要があります。

Linux 系だと、以下のような Makefile を書けばOK。

LDFLAGS += -lboost_thread-mt
all: cond

これで、make コマンドを実行するだけで、cond.cpp から cond が生成されます。

Windows だったら、libboost_thread-mt.lib をリンクすればOK。


なお posix 系と boostのAPIを比較すると

posix boost::thread系
pthread_cond_wait(&cond, &mutex) cond.wait(lock)
pthread_cond_timedwait(&cond, &mutex, &abstime) cond.timed_wait(lock, abstime)
pthread_cond_signal(&cond) cond.notify_one()
pthread_cond_broadcast(&cond) cond.notify_all()


詳細は boost本家のマニュアルを見ましょう。
http://www.boost.org/doc/libs/1_41_0/doc/html/thread/synchronization.html#thread.synchronization.condvar_ref