スレッド生成を少し使いやすくする

 何となくスレッド生成周りをまとめるついでに、

少し互換性(?)も上げてみる。

 方針としては、

・引数の削減

・型を一定にする

方向で。


 まずは、


/*=====================================
スレッドまとめヘッダ
=====================================*/

#ifndef __CREATE_THREAD__
#define __CREATE_THREAD__

// テスト用マクロ(※下記の「問題点」参照)
#define __WINAPI_THREAD__


//// ランタイムごとにスレッドの型定義
// WINAPI版

#ifdef __WINAPI_THREAD__
#include

typedef LPTHREAD_START_ROUTINE THREAD_FUNC;
#define THREAD_FUNC_CALL DWORD CALLBACK
typedef DWORD THREAD_ID;
typedef DWORD THREAD_CODE;
typedef HANDLE THREAD_HANDLE;

// Cランタイム版
#else
#include

typedef unsigned int (__stdcall *THREAD_FUNC)(void*);
#define THREAD_FUNC_CALL unsigned int __stdcall
typedef unsigned int THREAD_ID;
typedef unsigned int THREAD_CODE;
typedef uintptr_t THREAD_HANDLE;

#ifndef NULL
#define NULL (void*)0
#endif

#endif


// スレッド作成
THREAD_HANDLE CT_CreateThread( THREAD_FUNC thread_func,
void* thread_param,
THREAD_ID *thread_ID );
// スレッド終了
void CT_ExitThread( THREAD_CODE code );
// スレッド終了待機
void CT_WaitThreadEnd( THREAD_HANDLE thread,
THREAD_ID threadID );


#endif // __CREATE_THREAD__

こんな感じのヘッダを作っておいて、

#include "さっきのヘッダ"


/*=====================================
スレッド作成
=====================================*/

THREAD_HANDLE CT_CreateThread( THREAD_FUNC thread_func,
void* thread_param,
THREAD_ID *thread_ID )
{
#ifdef __WINAPI_THREAD__
return CreateThread( NULL, 0, thread_func,
thread_param, 0, thread_ID );
#else
return _beginthreadex( NULL, 0, thread_func,
thread_param, 0, thread_ID );
#endif
}
/*=====================================
スレッド終了
=====================================*/

void CT_ExitThread( THREAD_CODE code )
{
#ifdef __WINAPI_THREAD__
ExitThread( code );
#else
_endthreadex( code );
#endif

return;
}

/*=====================================
スレッド終了待機
=====================================*/

void CT_WaitThreadEnd( THREAD_HANDLE thread,
THREAD_ID threadID )
{
#ifdef __WINAPI_THREAD__
PostThreadMessage( threadID, WM_QUIT, 0, 0 );
WaitForSingleObject( thread, INFINITE );
CloseHandle( thread );
#else
#endif

return;
}

こんな感じでソースを書く。



 これで、


#include "さっきのヘッダ"


// スレッドで走らせる関数
THREAD_CALL ThreadFunc( void *param )
{
CT_ExitThread( 0 );
return 0;
}

...

THREAD_ID thread_ID = 0;

// スレッド作成
THREAD_HANDLE handle = CT_CreateThread( ThreadFunc,
param,
&(thread_ID) );

...

// スレッド削除
CT_WaitThreadEnd( handle, thread_ID );

こんな感じで少し楽に使えるようになるかな、と。





 …以下、問題点・気付いた点。

・ヘッダのマクロ(「__WINAPI_THREAD__」)は「__WIN32」とかにした方が正確。

 SDLのヘッダあたりを見て勉強しましょう。

・返り値の型が微妙に違う。(DWORDとunsigned int)

 コンパイラの警告レベル次第で怒られるので、ちゃんとtypedef。



!多分C言語単体の環境でも使えるはずだけど、

 頭に「_」の付いてる関数って、コンパイラ依存の可能性があるんじゃなかったっけ?

!互換性云々言ってる癖にWinとCランタイムのみ。

 他の環境のAPIとかはそんなに見たことないので、

 SDLのヘッダあたりを見て勉強しましょう。



?何かCALLBACK入ってるとtypedefできないんですが…?

?Cランタイムだけだとスレッド待ちできないのかな?