UWSCのスレッドを停止する
以前公式掲示板に、「スレッドの一時停止について」という投稿があった。
http://www3.bigcosmic.com/board/s/board.cgi?id=umiumi&mode=all&no=4952&log=ON&cnt=41
メインスレッドを一時停止する方法を尋ねるものでした。
改めてスレッドを止める方法を考えてみた。
結論としては、銀の弾はない、ですが、、、。
提案した方法
メインスレッドを一時停止したい、とのことなので、MSGBOXを出す方法を提案しました。
こんな感じ。
THREAD Loop("sub") THREAD Watch() Loop("main") PROCEDURE Loop(msg,wait=1) WHILE TRUE GETTIME() PRINT G_TIME_SS2 + " " + msg SLEEP(wait) WEND FEND PROCEDURE Watch() WHILE TRUE IF GETKEYSTATE(VK_ESC) THEN MSGBOX("Stop") SLEEP(0.1) WEND FEND
ESCキーを「ちょん」と押すと、MSGBOXが出てメイン側が止まるのがわかります。
監視用スレッドは止まりますが、サブ側Loopは止まりません。
MSGBOX以外にINPUTやSLCTBOXでも同様です。
ほとんどバッドノウハウであり、いつ仕様変更があってもおかしくないですが、今は止まるのです。
じゃあ、正攻法は?と考えた時、Win32APIを使うアイデアは微妙。
SuspendThread/ResumeThreadは、メインスレッドに使うのは非常に危険に思える。
→UWSCのメインスレッドは、管理を行っていると思われるため
ちなみに、サブスレッドに使うのも危険でしょう。
→サブスレッドが不自然に止まっているとUWSCがロックする模様。長時間止めるのは危険
デバッグ中くらいしか使えないかと思います。
となると、今のところ正攻法はなさそう。
考え方を変える。
忙しいなら処理しない
スレッドのプライオリティを下げてはどうでしょう。
メインスレッドにやるのはちょっと危険な気がしますが、サブなら良いかと。
DEF_DLL SetThreadPriority(DWORD,int): BOOL: kernel32 DEF_DLL GetCurrentThread(): DWORD: kernel32 THREAD Loop("sub", 1, -15) Loop("main", 0.001) PROCEDURE Loop(msg,wait=1,p=0) IF p THEN SetThreadPriority(GetCurrentThread(), p) WHILE TRUE GETTIME() PRINT G_TIME_SS2 + " " + msg SLEEP(wait) WEND FEND
メイン側が「がーっ」と出て、サブは少しになるかと思います。
実態にあわせて止める処理を書く
確かに、全ての処理に停止するコードを入れるのは、面倒です。
でも、本当に全ての箇所で必要でしょうか?
パレートの法則というのがあります。
人間(とろい)が止めたいと思った瞬間、その瞬間にもUWSC(はやい)は動いています。
例えばスレッドの処理ががーっとあっても、実際に止められる瞬間は、固定していませんか?
例えば負荷軽減のためのSLEEPとか、GETIDとか。
そこに一時停止する処理をさくっと入れましょう。
WHILE GETKEYSTATE(VK_ESC); SLEEP(0.1); WEND
こんなのも良いですね。
IF GETKEYSTATE(VK_ESC) THEN MSGBOX("一時停止中")
ただこれをサブでやると、前述のようにメインスレッドも停止します。