- PR -

スレッドハンドルが解放されない

1
投稿者投稿内容
Forte
会議室デビュー日: 2007/07/24
投稿数: 19
投稿日時: 2007-12-06 17:33
以前、質問を投稿させていただいた、さくさくと申します。
以前の質問内容が分かりにくいものだったので、もう一度投稿させてください。

質問の概要は、
メインスレッドからサブスレッドを立て、
サブスレッド終了後、そのスレッドハンドルが解放されない原因についてです。

環境--------------
OS:WindowsXP Pro SP-2
開発ツール:VisualStudio2005 Pro SP-1
開発言語:VisualC++ win32コンソールアプリケーション
プロジェクト設定:初期設定

新規作成したプロジェクトで、以下の様なコーディングをしました。

コード:
#include <windows.h>
#include <process.h>
#include "TEST.h"

/*-─────-───-───-──-──-──-─-─-─-─--─--─--─--─--─--─--─------------------------
 * スレッド関数
 *-─────-───-───-──-──-──-─-─-─-─--─--─--─--─--─--─--─----------------------*/
unsigned int __stdcall ThreadFunc(void* pv){
	TEST t;
	::_endthreadex(1);
	return 0;
}

/*-─────-───-───-──-──-──-─-─-─-─--─--─--─--─--─--─--─------------------------
 * メイン関数
 *-─────-───-───-──-──-──-─-─-─-─--─--─--─--─--─--─--─----------------------*/
void main()
{
	HANDLE h = NULL;

	// スレッドを作成、終了待ち、ハンドル解放
	h = (HANDLE)::_beginthreadex(NULL,0,&ThreadFunc,NULL,0,NULL);
	::WaitForSingleObject(h,-1);
	::CloseHandle(h);

	// スレッドを作成、終了待ち、ハンドル解放(繰り返し)
	h = (HANDLE)::_beginthreadex(NULL,0,&ThreadFunc,NULL,0,NULL);
	::WaitForSingleObject(h,-1);
	::CloseHandle(h);

	// スレッドを作成、終了待ち、ハンドル解放(繰り返し)
	h = (HANDLE)::_beginthreadex(NULL,0,&ThreadFunc,NULL,0,NULL);
	::WaitForSingleObject(h,-1);
	::CloseHandle(h);
}



ここで、"TEST.h"とは、以下の様なクラスのファイルになっています。


コード:

******* TEST.h ********
class TEST
{
public:TEST();
};
***********************

****** TEST.cpp *******
// このファイルのプロジェクト設定:共通言語ランタイムサポート・/clr
#include "TEST.h"

// コンストラクタ定義部
TEST::TEST(){}
***********************



このコードを要約すると、
メイン関数内でサブスレッドを作成し、サブスレッド上でThreadFunc関数を呼ぶ。
ThreadFunc関数内で、TESTクラスをインスタンス化する。
TESTクラスのcppファイルは、CLRを使用する。
といった具合です。


問題は、このコードを実行すると、
メインスレッドで作成されたサブスレッドのスレッドハンドルが異様に増えてしまいます。

タスクマネージャで確認したところ、スレッド起動時にハンドルが一つ増え、スレッド終了時(?)にハンドルが4〜5つ増えます。
その後CloseHandle関数を呼ぶと、ハンドルが一つ減ります。
つまり、計5〜6つ増えるのに、解放するのは一つだけという状態です。

また、"TEST.cpp"ファイルのプロジェクト設定を、
// このファイルのプロジェクト設定:共通言語ランタイムサポート・使用しない
にすると、ハンドルは一つだけ増え、CloseHandle関数で元に戻りました。

CLRを使用するファイルが有る場合は、ハンドル解放の仕方が別にあるのでしょうか?

この現象の原因、及び対策をご存知の方が居ましたら、是非教えてください。
囚人
ぬし
会議室デビュー日: 2005/08/13
投稿数: 1019
投稿日時: 2007-12-06 18:12
おもしろそうなので後で調べるかもしれませんが、とりあえず現状でのあてずっぽう発言を。

C++/CLI の挙動がどうなっているのか詳細は知りませんが、CLR が起動したなら少なくともガベージコレクションのためのスレッドが必要になるかもしれません。ただ、CLRの種類(サーバーバージョンかワークステーションバージョンか)とガベージコレクションの種類(平行ガベージコレクションか非並行ガベージコレクションか)に依るかもしれません。

加えて、ファイナライザのためのスレッドが必要です。

更に、スレッドプールがある程度のスレッドを抱えて準備を始めてるかもしれません。

などなど、考えられる事はいくつかあるようですね。



_________________
囚人のジレンマな日々

[ メッセージ編集済み 編集者: 囚人 編集日時 2007-12-06 18:13 ]
Forte
会議室デビュー日: 2007/07/24
投稿数: 19
投稿日時: 2007-12-06 19:08
囚人さん
返答ありがとうございます。

なるほどです。
"ガベージコレクションのためのスレッドハンドル"は何となくイメージしましたが、他にもCLRのためのスレッドがあるんですね。

そういったCLR特有のスレッドハンドルを解放するための手段として、
"RuntimeReleaseHandle"というそれっぽい関数を見かけたのですが、
この関数が定義されている"corpriv.h"ファイルの参照の仕方が分かりませんでした。。。

ただ、手動で開放する物じゃないだろうし、そもそもどのハンドルを解放すればいいのかも分からないんですよね。
Tdnr_Sym
ぬし
会議室デビュー日: 2005/09/13
投稿数: 464
お住まい・勤務地: 明石・神戸
投稿日時: 2007-12-07 00:26
こんばんは。

引用:

さくさくさんの書き込み (2007-12-06 19:08) より:
なるほどです。
"ガベージコレクションのためのスレッドハンドル"は何となくイメージしましたが、他にもCLRのためのスレッドがあるんですね。



SSCLI2.0のソースをみると、
GC thread
Gate thread
Timer thread
debugger helper thread
Finalizer thread
など、バックグラウンドで動いているらしきスレッドがありそうですね。
たぶん実際にはJITコンパイル用のスレッドも動くんだと思います。


ちなみにJavaVMでは、
VMThread
JavaThread(たぶんこれはJavaコードが処理されているスレッド)
CompilerThread
JVMPIDaemonThread
JvmtiAgentThread
WatcherThread
ConcurrentMarkSweepThread
LowMemoryDetectorThread
などがあるようです。
1

スキルアップ/キャリアアップ(JOB@IT)