ライブラリとして提供されている部分を,他のコードと分離するためコンソール 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 を利用した単体テスト用コード