Win32 APIを使っています。
ソートの勉強の為に
右クリックでシャッフル、左クリックでソートするプログラムを作りました。
ソートをスレッドで行なっています。
ソート中に右クリックを押すとシャッフルと同時にスレッドを破棄したいと思ったのですが
CreateThreadで作った特定のスレッドを破棄するにはどうしたらよいでしょうか?
GetExitCodeThreadとExitThreadを使って破棄すると思い
試してみたらプログラム自体が閉じてしまいました。
タスクマネージャで確認したらプログラム自体はあってウィンドウは表示されてない状態になりました。
No.1
- 回答日時:
普通は、スレッド側に「安全に終了する為の仕掛け」を入れ込んでおきます。
たとえば、イベントで通知するようにして、スレッド側は定期的(ループの中とか)にWaitForSingleObject()等でイベントの状態を確認します。
# 状況によってはWaitForMultipleObject()で。
UIスレッドからはSetEvent()などでスレッド側に終了を要求する。
というような流れになります。
# スレッドが終了したかどうか…をCreateThread()で作成した時のハンドルなどで判定する。
# ちなみに、Cランタイムとか使う場合はCreateThread()ではなく_beginthread()などを使います。
スレッド側に安全に終了する仕掛けを入れていない場合は、TerminateThread()で無理矢理殺すことになるでしょう。
リソースリークとか発生する可能性がありますのでご注意を。
>ExitThreadを使って破棄すると思い
>試してみたらプログラム自体が閉じてしまいました。
「現在実行しているスレッド」を終了するものです。
UIスレッドで実行したら…ウィンドウが破棄されたように見えるかもしれませんね。
で、他のスレッドが実行中なのでスレッド終了までプロセスが残っている(タスクマネージャに残っている)のでしょう。
# そのままゾンビと化す場合もありますかねぇ……。
その他、同期処理も必要ですのでその辺りには注意が必要です。
# 左クリックでソート実行中にもう一度左クリックするとどうなりますか?
# ダブルクリック判定されない程度の早さでクリックし続けるとどうなりますか?とか。
この回答への補足
回答ありがとうございます。
そういう風な使い方をするんですね。
Windowsゲームプログラミングという本を参考にしていましたが
SetEvent()やTerminateThread()などは載っていなくて
スレッドの破棄ではななく停止しかできなかったので困っていました。
ExitThread()は現在実行しているスレッドなんですね。
同期処理はミューテックスを使ってやっています。
具体的にCreateEvent()、SetEvent()、WaitForSingleObject()
などをどこに置くかがわからなかったので教えて欲しいです。
WaitForSingleObject()をSleepの代わりに使って
シグナル状態のときはSetEvent()を呼び出してスレッドに終了を要求するのでしょうか?
ただ>>UIスレッドからはSetEvent()などでスレッド側に終了を要求する。
というのを見ると違いますかね。
これはSetEvent()の中でどうスレッドに終了を要求するのでしょうか?
TerminateThread()ではまた同じ問題になってしまいますし・・・
理解がまだできてない部分が多いのでお願いします。
No.2ベストアンサー
- 回答日時:
>具体的にCreateEvent()、SetEvent()、WaitForSingleObject()
>などをどこに置くかがわからなかったので教えて欲しいです。
キーワードで検索して使用例とか探してみた方がいいのですが……
とりあえず、猫でも…で下記でしょうかね。
http://www.kumei.ne.jp/c_lang/intro2/no_103.htm
>WaitForSingleObject()をSleepの代わりに使って
>シグナル状態のときはSetEvent()を呼び出してスレッドに終了を要求するのでしょうか?
違います。
・メインスレッド側
M1.メインスレッド側でCreateEvent()でイベントを作成しておきます。(非シグナル状態で)
ハンドルは保持できるようにしておく必要があります。(グローバル変数でもプロシージャ内のstatic変数でもいずれかの方法で)
M2.メインスレッドからワーカースレッド(例としてシャッフルスレッド)を起動します。
ワーカースレッド起動後はメインスレッドは通常の処理に戻ります。
M3.メインスレッド側でワーカースレッドを終了したいタイミングでM1で作成したイベントをSetEvent()でシグナル状態にします。
・ワーカースレッド側
W1.ワーカースレッドは開始時にOpenEvent()でM1.で作成したイベントのハンドルを取得します。(イベントに名前を付けておく必要はありますが)
上記の猫でも…ではOpenEvent()はしていません。イベントハンドルをグローバル変数にしているから…ですが。
排他処理の関係でハンドルがおかしくなる場合があるかも知れませんのでグローバル変数使う場合はご注意を。
W2.ワーカースレッドのループ内でWaitForSingleObject()でイベントの状態を確認します。
第2引数に適当な値を入れてSleep()代わりに使うのもいいですし、0を指定してイベントの状態を確認するだけでもいいでしょう。
W3.WaitForSingleObject()の戻り値がWAIT_OBJECT_0の場合、メインスレッド側でスレッドの終了要求がされた(M3でのSetEvent()でシグナル状態)ということで、ワーカースレッドのループを抜けます。
W4.W1でOpenEvent()したハンドルを閉じて、他の後始末をした後でreturnします。
またはExitThread()します。
ざっくりこんな感じ…でしょうかね。
イベントハンドルの保持には気をつける必要があるでしょうけど。
ちなみに、同じワーカースレッドを複数回呼ぶ可能性があるのならば、W4でイベントハンドルを閉じる前にResetEvent()で非シグナル状態にしておく必要があるでしょう。
あるいは…W1でOpenEvent()した時にResetEvent()を実施か、M2でワーカースレッド呼び出す前にResetEvent()を実施。
# CreateEvent()時に第2引数で自動リセットに設定したら…ResetEvent()は不要ですかね。試したコトないですけど。
デッドロックにはご注意を。
# たとえば、M2で通常の処理に戻った時にワーカースレッドのハンドルで終了を待つ…とか。
# ワーカースレッドが時間がたてば終了するなら問題はないですが、外部から終了の契機を与えるまで終わらないタイプだと操作出来なくなってしまいますから。
なんというか、既に「ソートの勉強」ではなくなってますけども。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- PHP htmlspecialcharsが機能していないです。 バグですか? 1 2022/04/05 01:22
- PHP ここでの ②if($su_d<>"")の比較演算子 を使う理由は 1 2022/03/26 02:33
- PHP if(preg_match("/[^0-9]/",$gu_d)){意味を教えてください。 1 2022/05/06 05:37
- C言語・C++・C# 10個の実数に対する降順ソート結果を出力するプログラムを作りたいのですが、写真のプログラムをどう直せ 2 2022/07/09 21:13
- Excel(エクセル) Excelの50音順ソートを全ての行列に適用するには? 4 2022/12/05 11:28
- 音楽・動画 ノートパソコンで動画再生の設定の変更について*長文ですが何卒宜しくお願い致します。 3 2022/10/18 12:24
- Windows 10 windows11 update の「更新の再開」について初歩的な質問なのですが 1 2022/10/19 00:57
- C言語・C++・C# 10個の実数に対する降順ソート結果を出力するプログラムを作りたいのですが、以下のプログラムをどう直せ 1 2022/07/09 22:16
- Excel(エクセル) Excel 効率的な名簿と得点の管理の仕方 8 2022/08/07 08:15
- Windows 10 (緊急)windowsのタスクバーやアプリ?が反応しない 3 2023/03/28 05:03
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
スレッドの安全な終了のさせ方
-
WaitForSingleObjectの使い方に...
-
DirectX LPDIRECT3DDEVICE9のマ...
-
自作クラスのイベントを外部ハ...
-
マルチスレッドプログラム
-
マルチスレッドについて
-
.netアプリへのSendMessageでフ...
-
スレッドにて同一メモリの書き...
-
マルチスレッドプログラムでメ...
-
win32 スレッドのハンドルついて
-
緯度、経度の 10進法と 60進法...
-
Macターミナルで実行中のプログ...
-
VBAの配列サイズとメモリに関して
-
バックグラウンドのプロセスの...
-
Excelでのセル内容の高速消去方法
-
explorer.exeが異様にメモリを食う
-
C言語で、メモリを解放しないで...
-
VBSで応答不要のメッセージボッ...
-
MACで動く実行ファイルをWindow...
-
VBSの処理中一旦処理を止めて再...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
WaitForSingleObjectの使い方に...
-
スレッドにて同一メモリの書き...
-
VC++スレッドの正しい終了のさ...
-
スレッドの監視方法について
-
Windows上で、シグナル(SIGTERM...
-
スレッドの終了の仕方
-
スレッドの安全な終了のさせ方
-
CWnd::OnTimerのスレッドの取得
-
MFC通信プログラムマルチスレッ...
-
Linuxでスレッド優先度って変え...
-
.netアプリへのSendMessageでフ...
-
VB2005 シリアル通信のClose処理
-
スレッドの終了はどうやるんで...
-
別スレッドからメインダイアロ...
-
マルチスレッドについて
-
マルチスレッドプログラミング...
-
別スレッドのデータを受信できない
-
特定のスレッドの破棄
-
.NetのBackgroundWorkerクラス...
-
msec単位のWait Timerが作れない!
おすすめ情報