このサイトによると、スレッドの処理が終了してもスレッドオブジェクトは自動で解放されないようです。
ただ、「マルチスレッドは親プロセスのメモリ空間を共有します」とあるため、WinMain関数が終了し、プログラム自体がシステムから削除された場合はそれに伴いスレッドオブジェクトも削除されるものと思われます。
まず、この解釈で合っているでしょうか?
そうならば、プログラム終了時「走っているスレッドを見つけて終了させて解放して」なんていう茶番をせずに済みますね。
次に、スレッドの処理が終了した後スレッドオブジェクトを解放する際のお話をします。
いくらプログラムが終了したら解放されると言っても、スレッドを作り続けて1つも解放しないというのは良くないでしょう。
一番簡単なのは、スレッドの処理の最後で自分自身を解放してしまう方法です。
実験してみました。
main.cpp
#include "thread.h"
#include "stdio.h"
fw_thread_ func(void * param){
printf("start");
CloseHandle(param);
printf("closed");
return 1;
}
int main(){
fw::thread t(func, false);
t.begin(t.gethandle() );
return(0);
}
#pragma once
#include <windows.h>
#include <stdexcept>
#define fw_thread_ DWORD WINAPI
namespace fw{
class thread{
HANDLE handle;
DWORD Result;
LPTHREAD_START_ROUTINE myfunc;
void * myparam;
void nullet(){
handle = NULL;
myfunc = NULL;
myparam = NULL;
}
public:
bool begin(LPTHREAD_START_ROUTINE func, void * param = NULL){
void * p = param;
if(p==NULL) p = myparam;
if(func==NULL){
#ifdef FW_THREAD_POP_UP_
fw::popup("呼び出す関数が指定されていないか、もしくは無効です","fw::threadエラー");
#endif
throw std::invalid_argument("fw::thread_func_error");
}
handle = CreateThread( NULL, 0, func, param, 0, LPDWORD() );
return true;
}
bool begin(void * param){
return begin(myfunc, param);
}
bool begin(){ return begin(myfunc, myparam); }
thread(){ nullet(); }
void set(LPTHREAD_START_ROUTINE func, void * param){
nullet();
myfunc = func;
myparam = param;
}
thread(LPTHREAD_START_ROUTINE func, void * param, bool flag=true){
set(func, param);
if(flag) begin();
}
void set(LPTHREAD_START_ROUTINE func){
nullet();
myfunc = func;
}
thread(LPTHREAD_START_ROUTINE func, bool flag=true){
set(func);
if(flag) begin();
}
void set(void * param){
nullet();
myparam = param;
}
thread(void * param){ set(param); }
bool working(){
GetExitCodeThread(handle , &Result);
if(Result == STILL_ACTIVE) return true;
CloseHandle(handle);
return false;
}
bool working(unsigned long & target){
if(working() ) return true;
target = Result;
return false;
}
bool resting(){
return !working();
}
//*
void * gethandle() const { return handle; }
//*/
unsigned long result(){ return Result; }
};
}
ということは、少なくともCloseHandle関数を呼び出すとスレッド処理が終了する(もしくは停止する)ということですね。
ただ、スレッドオブジェクトは解放されているのかという肝心な部分は確かめようがなかったですね。
実際のところどうなのでしょうか?