動き探索がやたらと遅いのでSSEを使おうと思ったら16[bit]整数の128[bit]飽和乗算が無くて、結局MMXかよ!、という今日この頃ですが、デュアルコアCPUも増えてきたし、そろそろマルチスレッドにしないとなー、という事でやってみました。

コンパイル環境はMinGWです。windowsのapiを使うので色々ライブラリをリンクしないといけないと思っていたのですが、すんなり
 g++ test.cpp
で通ってしまいました。

という事でスレッドを立てて終了を待つコード。

#include
#include "stdio.h"

//スレッドに渡す引数
struct Args{
int data1;
int data2;
};

//スレッドで動かす関数本体
void thread_main(const Args *a){
 printf("引数:%d %d\n",a->data1,a->data2);
 for(unsigned int i=0;i<100;i++){
  printf("%d ",i);
  Sleep(10);
 }
}

//メイン
int main(void){
 //スレッド関数に渡す引数を準備
 Args args;
 args.data1=123;
 args.data2=456;

 //スレッドの作成
 DWORD id=1; //スレッドのID
 HANDLE hThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)thread_main, (LPVOID)&args, 0, &id);

 //スレッド終了待ち
 DWORD result=STILL_ACTIVE;
 while(result==STILL_ACTIVE){
  GetExitCodeThread(hThread, &result);
 }
}

うん、楽だ。ただ、staticなメンバ関数しかスレッドを立てられない。そこをごまかすにはstaticでないクラスメンバ関数を_beginthreadで実行させる方法をやらないといけないみたい。

ということでstatic関数を媒介にしてメンバ関数を呼び出す例。ようするにCreateThreadに渡す関数の呼び出し規約は__cdeclである必要があるので、__cdeclなstatic関数に一度投げて、引数にクラスへのポインタを渡すことでメンバ関数を実行すると。

#include
#include "stdio.h"

//スレッドで動かす関数本体
class ThreadTest{
public:
 //CreateThreadに渡す関数は__cdeclである必要
 static void exec_thread(void *args){
  reinterpret_cast(args)->thread_main();
 }

 //スレッドメンバ関数
 void thread_main(void) const{
  for(unsigned int i=0;i<100;i++){
   printf("%d ",i);
   Sleep(10);
  }
 }
};

//メイン
int main(void){
 //スレッドの作成
 ThreadTest thread_test;
 DWORD id=1; //スレッドのID
 HANDLE hThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)thread_test.exec_thread, (LPVOID)&thread_test, 0, &id);

 //スレッド終了待ち
 DWORD result=STILL_ACTIVE;
 while(result==STILL_ACTIVE){
  GetExitCodeThread(hThread, &result);
 }
}

うん、いい気がする。