기본적인 원리는 크리티컬 섹션과 같습니다만, 크리티컬 섹션이 유저 모드 동기화 방법인 반면...
뮤텍스는 커널 모드 동기화 방법입니다.
또, 뮤텍스는 서로 다른 프로세스의 쓰레드 사이에도 동기화를 수행할 수 있습니다.
WaitForSingleObject 로 뮤텍스를 획득하고, ReleaseMutex 로 뮤텍스를 반납합니다.
뮤텍스 사용시의 흐름도는 다음과 같습니다.
1. HANDLE hMutex;
핸들을 하나 선언합니다.
2. hMutex = CreateMutex (
NULL, // 디폴트 보안관리자.
FALSE, // 누구나 소유 할 수 있는 상태로 생성.
NULL // numaned mutex
);
뮤텍스를 생성합니다.
3. WaitForSingleObject(hMutex, INFINITE);
임계영역 진입직전에 뮤텍스를 획득합니다.
4. ReleaseMutex(hMutex);
임계영역에서 나오자마자 뮤텍스를 반환합니다.
5. CloseHandle(hMutex);
더이상 뮤텍스를 사용할 경우가 없거나, 프로그램 종료시에 뮤텍스를 해제합니다.
아래는 뮤텍스를 사용한 예제입니다.
- /*
- CriticalSectionSyncMutex.cpp
- 프로그램 설명: 크리티컬 섹션과 뮤텍스 비교
- */
- #include <stdio.h>
- #include <windows.h>
- #include <process.h>
- #include <tchar.h>
- #define NUM_OF_GATE 6
- LONG gTotalCount = 0;
- // CRITICAL_SECTION gCriticalSection;
- HANDLE hMutex;
- void IncreaseCount()
- {
- // EnterCriticalSection (&gCriticalSection);
- WaitForSingleObject(hMutex, INFINITE);
- gTotalCount++;
- // LeaveCriticalSection (&gCriticalSection);
- ReleaseMutex(hMutex);
- }
- unsigned int WINAPI ThreadProc( LPVOID lpParam )
- {
- for(DWORD i=0; i<1000; i++)
- {
- IncreaseCount();
- }
- return 0;
- }
- int _tmain(int argc, TCHAR* argv[])
- {
- DWORD dwThreadIDs[NUM_OF_GATE];
- HANDLE hThreads[NUM_OF_GATE];
- // InitializeCriticalSection(&gCriticalSection);
- hMutex = CreateMutex (
- NULL, // 디폴트 보안관리자.
- FALSE, // 누구나 소유 할 수 있는 상태로 생성.
- NULL // numaned mutex
- );
- if (hMutex == NULL)
- {
- _tprintf(_T("CreateMutex error: %d\n"), GetLastError());
- }
- for(DWORD i=0; i<NUM_OF_GATE; i++)
- {
- hThreads[i] = (HANDLE)
- _beginthreadex (
- NULL,
- 0,
- ThreadProc,
- NULL,
- CREATE_SUSPENDED,
- (unsigned *)&dwThreadIDs[i]
- );
- if(hThreads[i] == NULL)
- {
- _tprintf(_T("Thread creation fault! \n"));
- return -1;
- }
- }
- for(DWORD i=0; i<NUM_OF_GATE; i++)
- {
- ResumeThread(hThreads[i]);
- }
- WaitForMultipleObjects(NUM_OF_GATE, hThreads, TRUE, INFINITE);
- _tprintf(_T("total count: %d \n"), gTotalCount);
- for(DWORD i=0; i<NUM_OF_GATE; i++)
- {
- CloseHandle(hThreads[i]);
- }
- // DeleteCriticalSection(&gCriticalSection);
- CloseHandle(hMutex);
- return 0;
- }