動作環境
C++ Builder XE4
RAD Studio 10.2 Tokyo Update 2 (追記: 2018/01/05)
TMutexを試した。
注意 (下記のコードは
Case 1. ロックがかからない
Unit1.cpp
//---------------------------------------------------------------------------
#include <vcl.h>
#pragma hdrstop
#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------
String MutexName = L"Project1";
TMutex *myMutex;
HWND HWNDMutex;
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
}
//---------------------------------------------------------------------------
void __fastcall TForm1::FormCreate(TObject *Sender)
{
myMutex = new TMutex(false);
}
void __fastcall TForm1::FormClose(TObject *Sender, TCloseAction &Action)
{
delete myMutex;
myMutex = NULL;
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button1Click(TObject *Sender)
{
myMutex->Acquire();
String msg1 = L"Start:" + Now().DateTimeString();
Memo1->Lines->Add(msg1);
for(int loop=0; loop < 50; loop++) {
Application->ProcessMessages();
Sleep(100); // msec;
}
myMutex->Release();
String msg2 = L"End:" + Now().DateTimeString();
Memo1->Lines->Add(msg2);
}
//---------------------------------------------------------------------------
Button1を連打した結果が以下。
結果(Memo1)
Start:2017/11/08 17:16:18
Start:2017/11/08 17:16:18
Start:2017/11/08 17:16:19
End:2017/11/08 17:16:24
End:2017/11/08 17:16:29
End:2017/11/08 17:16:33
Startのメッセージ表示は2秒内に3つ処理されている(ロックがかかっていない)。
Endのメッセージ表示は5秒弱間隔になっている(ロックがかかっている)。
Case 2. ロックがかかる例
Acquire()の後に200msecほど「待ち」を入れるときちんとロックされるようだ。
(100msecの待ちではロックされなかった)。
Unit1.cpp
//---------------------------------------------------------------------------
#include <vcl.h>
#pragma hdrstop
#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------
String MutexName = L"Project1";
TMutex *myMutex;
HWND HWNDMutex;
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
}
//---------------------------------------------------------------------------
void __fastcall TForm1::FormCreate(TObject *Sender)
{
myMutex = new TMutex(false);
}
void __fastcall TForm1::FormClose(TObject *Sender, TCloseAction &Action)
{
delete myMutex;
myMutex = NULL;
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button1Click(TObject *Sender)
{
myMutex->Acquire();
for(int loop=0; loop < 20; loop++) {
Application->ProcessMessages();
Sleep(10); // msec;
}
String msg1 = L"Start:" + Now().DateTimeString();
Memo1->Lines->Add(msg1);
//Update();
for(int loop=0; loop < 50; loop++) {
Application->ProcessMessages();
Sleep(100); // msec;
}
myMutex->Release();
String msg2 = L"End:" + Now().DateTimeString();
Memo1->Lines->Add(msg2);
}
//---------------------------------------------------------------------------
結果(Memo1)
Start:2017/11/08 17:25:35
End:2017/11/08 17:25:40
Start:2017/11/08 17:25:40
End:2017/11/08 17:25:45
Start:2017/11/08 17:25:45
End:2017/11/08 17:25:50
Case 3. TCriticalSection
TMutexの代わりにTCriticalSectionを試した。
Case2と同様の200msecの「待ち」ではロックがうまく動作しなかった。
300msecの「待ち」ではロックがかかった。
Case 4. Boost::scoped_lock
下記の場合は、Case2と同様に200msecの「待ち」を必要とした。
boost::mutex::scoped_lock(s_mutex);