ライブラリとして提供されている部分を,他のコードと分離するためコンソール AP(変換 exe)として作成.
テスト用にそれを呼出す部分も別のコンソール AP(呼出 exe)として作成.
変換 exe は,aaa.dat を aaa.txt の様に異なる形式に変換する機能.
呼出 exe は,::ShellExecute(…,”変換.exe aaa.dat”,…) の様に呼出し aaa.txt を処理する.
データにより変換(*.dat から *.txt へ)時間は数秒から数時間.
変換できたかどうかをチェックしている部分は次の様なコード.
for (size_t index=0 ; index<1000 ; index++) { ::Sleep(100) ; if (::File_IsExist(g3d_name)) { break ; } }
データが悪いのか,ライブラリの問題なのかは不明たが,変換 exe の中でエラーになってしまうことがある.
エラーを軽減する方法はわかっているが,それでも完全ではない.
同じデータでも通る時とそうでないことがあり不安定.
そのため,変換後データが存在しない時に,変換中でなければ「変換 exe」を再起動させなければならない.
2021/03/09
ここまでの部分を単体のコードとして作成.
t_call.cpp
t_conv.cpp
T_mtex_2021_03_09.zip
これらのコードでの問題は,
* 異常終了が判断できない.
* 変換に時間がかかる時,複数回呼んでしまう.
起動しているかどうかは Mutex を使えば良さそう.
変換 exe が起動している間,::CreateMutex (…,”入力ファイル名”) で作成したものを保持する.
呼出 exe のループでは,その Mutex が存在するかチェック.
なくなった時に,出力ファイルが存在している時はループを抜ける.
出力ファイルが存在していない時は,もう一度「変換 exe」を呼出す.
今まで作成の Mutex を使用したコード.
Prevent2.hxx Prevent2.cxx
ExclusS.hxx
t_conv.cpp
bool test (const tstring& name_in_) { tstring f_name = ::Path_GetName(name_in_) ; HANDLE hMutex = ::CreateMutex(NULL,FALSE,f_name.c_str()) ; time_t now = ::time(NULL) ; if ((now % 3) == 0) { ::Sleep(3000) ; tstring name_out = name_in_ + _T(".out") ; tstring name_uni = ::Get_unique_name(name_out) ; ::File_CreateEmpty(name_uni) ; } else { ::Sleep(500) ; } ::CloseHandle(hMutex) ; return true ; }
t_call.cpp
bool t_call (c_tstring& in_name_) { tstring name_in_ = in_name_ ; { tstring f_name = ::Path_GetName(name_in_) ; HANDLE hMutex = ::CreateMutex(NULL,FALSE,f_name.c_str()) ; DWORD error = ::GetLastError() ; ::CloseHandle(hMutex) ; if (error == ERROR_ALREADY_EXISTS) { return true ; } } tstring this_exe = ::i_GetModuleFileName() ; tstring conv_exe = ::Path_AddLastSP(::Path_GetDir(this_exe)) + _T("t_conv.exe") ; name_in_ = ::QuotM_Add_Auto(name_in_) ; // ... // 変換 exe を起動 // ... return true ; }
2021/03/10 更にクラスに.W_mutex.hxx
次の様にできる.
bool test (const tstring& name_in_) { W_mutex mutex(::Path_GetName(name_in_).c_str()) ; time_t now = ::time(NULL) ; if ((now % 3) == 0) { ::Sleep(3000) ; tstring name_out = name_in_ + _T(".out") ; tstring name_uni = ::Get_unique_name(name_out) ; ::File_CreateEmpty(name_uni) ; } else { ::Sleep(500) ; } return true ; } bool t_call (c_tstring& in_name_) { tstring name_in_ = in_name_ ; { W_mutex mutex(::Path_GetName(name_in_).c_str()) ; if (mutex.Is_exist()) { return true ; } } tstring this_exe = ::i_GetModuleFileName() ; tstring conv_exe = ::Path_AddLastSP(::Path_GetDir(this_exe)) + _T("t_conv.exe") ; name_in_ = ::QuotM_Add_Auto(name_in_) ; // ... return true ; }
2021/12/01
W_mutex を利用した単体テスト用コード
[…] SDI exe でファイルをドロップされた時,関連する異なるファイルを開きたくなった. 次の様に,変換済みのデータが存在している時はそれを対象とする. https://dev.mish.work/wordpress/2021/03/03/win-prevent-2nd/ […]