C++ Builder XE4, 10.2 Tokyo > TMutex, TCriticalSection: thread affinity | TSemaphore: not thread affinity | semaphore의 잠금 코드

운영 환경
C++ Builder XE4
RAD Studio 10.2 Tokyo Update 2 (追記: 2018/01/05)

관련



C++ Builder > TMutex > { 잠겨 있지 않은 예 | 잠긴 예 } |

링크



위의 링크에서는 록이 예상대로는 아니었다.

stackoverflow 에서 질문을 했지만 Remy Lebeau에게 자세한 답변을 받았습니다.

답변 개요
(해석 실수가 있을지도 모릅니다)
  • TMutex: thread affinity
  • TCriticalSection: thread affinity
  • TSemaphore: thread affinity가 아니다
  • Thread affinity의 경우, TTimer로의 락은 할 수 없다
  • 이들로부터 TSemaphore에서는 TTimer의 락은 가능
  • 뮤텍스는 inter-thread 동기화로 사용됩니다
  • TTimer 2 개에서는 single thread로서 동작하기 때문에, mutex는 useless

  • code



    stackoverflow에서 TSemaphore를 사용한 잠금 예를 소개했다.

    Unit1.cpp
    //---------------------------------------------------------------------------
    
    #include <vcl.h>
    #pragma hdrstop
    
    #include "Unit1.h"
    //---------------------------------------------------------------------------
    #pragma package(smart_init)
    #pragma resource "*.dfm"
    TForm1 *Form1;
    //---------------------------------------------------------------------------
    
    
    HANDLE hSemaphore;
    
    
    __fastcall TForm1::TForm1(TComponent* Owner)
        : TForm(Owner)
    {
    }
    
    __fastcall TForm1::~TForm1()
    {
        if (hSemaphore)
            CloseHandle(hSemaphore);
    }
    
    void __fastcall TForm1::FormShow(TObject *Sender)
    {
        hSemaphore = CreateSemaphore(NULL, 1, 1, NULL);
        if (hSemaphore == NULL) {
            OutputDebugString(L"failed to create semaphore");
        }
    
        Timer1->Enabled = false;
        Timer1->Interval = 1000; // msec
        Timer1->Enabled = true;
    
        Timer2->Enabled = false;
        Timer2->Interval =  200; // msec
        Timer2->Enabled = true;
    }
    //---------------------------------------------------------------------------
    void __fastcall TForm1::Timer1Timer(TObject *Sender)
    {
        if (WaitForSingleObject(hSemaphore, 0) != WAIT_OBJECT_0) {
            return;
        }
    
        if (CHK_update->Checked) {
            String msg = L"Timer1 " + Now().FormatString(L"yyyy/mm/dd hh:nn:ss.zzz");
            Memo1->Lines->Add(msg);
        }
    
        for(int loop=0; loop<10; loop++) {
            Application->ProcessMessages();
            Sleep(90); // msec
        }
    
        ReleaseSemaphore(hSemaphore, 1, NULL);
    }
    //---------------------------------------------------------------------------
    void __fastcall TForm1::Timer2Timer(TObject *Sender)
    {
        if (WaitForSingleObject(hSemaphore, 0) != WAIT_OBJECT_0) {
            return;
        }
    
        if (CHK_update->Checked) {
            String msg = L">>>Timer2 " + Now().FormatString(L"yyyy/mm/dd hh:nn:ss.zzz");
            Memo1->Lines->Add(msg);
        }
    
        ReleaseSemaphore(hSemaphore, 1, NULL);
    }
    //---------------------------------------------------------------------------
    

    제대로 락이 걸렸다.


    비고



    mutex, critical section, semaphore 등의 기구에 대해서는 아직 학습도가 얕다.

    좋은 웹페이지 즐겨찾기