pthread練習

そろそろやっとこうかと。

#include <pthread.h>
#include <iostream>

class Thread
{
  pthread_t id;
  pthread_mutex_t mutex;
  pthread_cond_t condition;

public:
  // used from main
  template<typename FUNC>
  void main_Start(FUNC func)
  {
    pthread_mutex_init(&mutex, NULL);
    pthread_cond_init(&condition, NULL);
    pthread_create(&id, NULL, func, this);
  }

  void main_SendSignal()
  {
    pthread_cond_signal(&condition);
  }

  template<typename RESULT>
  void main_Join(RESULT **pResult)
  {
    pthread_join(id, (void**)pResult);
  }

  // used from thread func
  void task_WaitCondition()
  {
    pthread_mutex_lock(&mutex);
    pthread_cond_wait(&condition, &mutex);
    pthread_mutex_unlock(&mutex);
  }
};

struct Result
{
  std::string message;
};

void *func(void *arg)
{
  std::cout << "thread: start." << std::endl;
  Thread &thread= *((Thread*)arg);
  std::cout << "thread: wait condition." << std::endl;
  thread.task_WaitCondition();
  std::cout << "thread: catch signal." << std::endl;

  sleep(3);

  Result *pResult=new Result;
  pResult->message="uho!";
  std::cout << "thread: finished." << std::endl;
  return pResult;
}

int main(int argc, char **argv)
{
  std::cout << "main: start." << std::endl;
  Thread thread;
  thread.main_Start(func);

  sleep(3);

  // send condition
  std::cout << "main: send signal." << std::endl;
  thread.main_SendSignal();

  // wait terminate
  std::cout << "main: wait join." << std::endl;
  Result *pResult;
  thread.main_Join(&pResult);
  std::cout << "main: result -> " << pResult->message << std::endl;

  delete pResult;

  return 0;
}

$ g++ thread.cpp -lpthread

main_Startがテンプレートなのは関数ポインタのシグネチャを書くのを手抜きするためと
後でファンクタを受け取れるように拡張するための布石。
pthreadの使い方が理解できたらclx thread
http://d.hatena.ne.jp/tt_clown/20080813/p1
を使う予定。
boost::threadはリンクが要るから敬遠。


今回のコードは、
こちらを参考にさせていただきました。
http://d.hatena.ne.jp/mononoco/20080522/1211452506