/*
  吉田弘一郎さんの名著「極めるVisual C++」の中P.133に記載のある、
  「スレッドのオブジェクト化」というコードが実に美しくて何度も
  利用させて頂きました。
  
  「start()メソッドで叩くだけで、オブジェクトがそのままスレッド
  となって動き出す」というもので、通信系やシミュレーションなどで
  これまで、大活躍して貰いました。

  この度MinGW(mingw64)でも動かせるか試してみたところ、稼働を確認
  しましたので、ソースコードを公開しておきます
  
*/

// gcc -g cthread.cpp -o cthread -lpthread

#include <stdio.h>
#include <pthread.h>
#include <unistd.h>  // getpid(), usleep()


class CThread
{
public:
  pthread_t thread_id; // スレッド番号
  pid_t   pid; // プロセス番号

  CThread(){
    // 初期処理があれば記載
    pid=getpid();
    thread_id=pthread_self();
  }
  
  void ThreadFunc();
  void start();
  void end();
};

// スレッドの中身(中身はなんだっていい)
void CThread::ThreadFunc() 
{
  int     i;
  
  for(i=0;i<10;i++){
    usleep(1);
    printf("[PID:%d][TID:%d] i=%d\n",pid,thread_id,i);
  }
  
  // return(arg);
};

  // メンバ関数ThreadFunc()をキックする為のグローバル関数
void __ThreadFunc(CThread *thread){
  thread->ThreadFunc();
}

void CThread::start(){
  // メンバ関数ThreadFunc()を、グローバル関数"__ThreadFunc"を経由して起動する
  pthread_create(&thread_id,NULL,(void *(*)(void *))&__ThreadFunc,this);
  // 失敗処理は省略

};

void CThread::end(){
  // 他のスレッドの終了を待つ
  pthread_join(thread_id,NULL);
 
};
 
int main()
{
  CThread thread1, thread2;

  thread1.start();
  thread2.start();

  thread1.end();
  thread2.end();

}