VCでのスレッド作成


229,561

Yesterday: 24 Today: 3

connected: via IPv4

VCでのスレッド作成


症状

CreateThreadを使ってスレッドを作成し、Cのランタイムライブラリの関数を使用した場合は ExitThread関数を呼び出したときにわずかなメモリリークが発生します。

MSDN 2001/01/16現在

対処

Cのランタイムライブラリを使用する場合はMSDNどおりに_beginthreadもしくは_beginthreadexを使用してやる必要があります。

しかしながらプライオリティの設定等や、スレッドの終了の検出等を行いたいときにはCreateThread戻すスレッドハンドルにあたるものが_beginthread, _beginthreadexでははっきりと記述されていないようです。MSDNにも見当たりません。

MSDN 2001/01/16現在

_beginthread

_beginthreadの場合は、_beginthreadが返す値(unsigned long)をHANDLEにキャストして格納してやれば、その後にSetThreadPriorityやWaitForSingleObject等が使用できます。スレッドの作成に失敗した場合は-1が戻ってきます。

しかしながらCreateThreadの時のようにCloseHandleでハンドルを閉じてはいけないようです。

_beginthreadex

_beginthreadexの場合は、_beginthreadのときのように返す値(unsigned long)をHANDLEにキャストして使用してください。スレッドの作成に失敗した場合はが戻ってきます。

CreateThreadの時のようにCloseHandleでハンドルを閉じなければいけないようです。でないとハンドルリークします。

6番目のthrdaddrはただ単なるスレッドIDが戻ってくるだけです。

プライオリティの設定

_beginthread や _beginthreadex の戻り値(unsigned long)を HANDLE にキャストして得たハンドルに対して SetThreadPriority を呼び出してプライオリティ(優先度)を設定してください。

	HANDLE hHandle = (HANDLE)_beginthread( ... );

	SetThreadPriority( hHandle , THREAD_PRIORITY_BELOW_NORMAL );	// 通常よりも一段階優先度を下げる。
	/*
		バックグラウンドで巨大なファイルをコピーするなどのときによく使われます。
	*/

スレッドの終了の検出

_beginthread や _beginthreadex の戻り値(unsigned long)を HANDLE にキャストして得たハンドルに対して WaitForSingleObject か WaitForMultiObject を呼び出してスレッドハンドルがシグナル状態になるまで待ってください。

	HANDLE hHandle = (HANDLE)_beginthread( ... );

	// 処理やメッセージループをまわす。

	WaitForSingleObject( hHandle , INFINITE );	// スレッドが終了するまで待機しつづける。
	/*
		ユーザーインターフェイスを担当しているスレッドを終了するときに、
		バックグラウンドで走るスレッドが終了するまで待機したいときに使います。

		INFINITE だと終了するまで待機するのでスレッドが終了しない場合は、
		プログラム自体の処理が進まなくなります。

		タイムアウト時間を設定して何度かリトライしてみてください。
		それでもだめな場合はスレッドハンドルの後処理を行ってから
		ユーザーにメッセージを出すなりして終了すればいいかと思います。

		ただしメモリリークなどが起きるのであまりお勧めできません。
		プログラムの作り方に問題があるかもしれないので原因追求は行ってください。
	*/


last update at 2010/11/09 19:17:07