今日は二重起動の防止処理を入れました。
※今日の日記は、かなりマニアックです。
アイコンのダブルクリックを勢い余って、トリプルクリックすると、
プログラムが二重起動してしまいますよね。
それを避けるルーチンをHSPで実現できるみたいなので、組み込んでみました。
スクリプトは、こちらを参考にさせていただきました。
HSPで二重起動を防止するには、3つの方法があるみたいです。
●方法1.
(1) プログラム起動時になんでもいいからファイルを作成する。
(2) (1)で作ったファイルがあったら、強制終了
(3) プログラム終了時に(1)のファイルを消す
⇒二番目に起動したプログラムは(2)ではじかれて終了する。●方法2.
(1) 起動プログラムにtitleを設定
(2) HSPEXT.DLLのaplsel関数で、(1)と同じタイトルのプログラムを探す
(3) (2)が見つかったら、強制終了
⇒二番目に起動したプログラムは(3)ではじかれて終了する。●方法3.
Kernel32.dllのミューテックス関数を使う方法#uselib "kernel32.dll"
#func CreateMutexA "CreateMutexA" sptr,int,sptr
#func CloseHandle "CloseHandle" sptr
#func GetLastError "GetLastError"#define ERROR_ALREADY_EXISTS 183
CreateMutexA 0,0,"yonkoushi"
mutex_handle=stat ; Mutexのハンドルを取得; エラーを確認
GetLastError; すでにMutexが存在していた!(存在していてMutexが作成できなかった)
if stat=ERROR_ALREADY_EXISTS {
dialog "2重起動されています!!",1
end
}
3つ方法がありますが、私は方法3を選びました。
アトミックなレベルの処理に堅牢性がありそうだと思ったのです。
アトミックなレベルとは、例えば、
以下のスレッド1とスレッド2が同時に実行されてようないるとき、
<スレッド1>
*aaa
if( flag = 0 ){
flag += 1
処理1
flag = 0
}
else{
goto *aaa
}<スレッド2>
*bbb
if( flag = 0 ){
flag += 1
処理2
flag = 0
}
else{
goto *bbb
}
上のスレッド1とスレッド2が同時に実行されているとき、
処理1と処理2は、flag変数の関係で、
同時には実行されないかのように見えます。
ところが、『flag += 1』をマシン語レベルで見ると、
となっているわけです。
メモリから読み出す。
加算する
書き込む
で、二重起動のタイミングが悪いと、
となって二重起動を防げないわけです。
1番目のプログラムが起動する
メモリから読み出す(flag == 0)
加算する
2番目のプログラムが起動する
メモリから読み出す(flag == 0)
書き込む(flag == 1)
加算する
書き込む(flag == 1)
その点、ミューテックスを使えば、マシン語のレベルで
競合を回避できるということですね!
ただ1つ気になるのは、VISTAとかでもちゃんと動くのかなってことですかね?
大丈夫だとは思うのですが…。