System2008. 11. 25. 15:37

기본적인 원리는 크리티컬 섹션과 같습니다만, 크리티컬 섹션이 유저 모드 동기화 방법인 반면...
뮤텍스는 커널 모드 동기화 방법입니다.
또, 뮤텍스는 서로 다른 프로세스의 쓰레드 사이에도 동기화를 수행할 수 있습니다.



WaitForSingleObject 로 뮤텍스를 획득하고, ReleaseMutex 로 뮤텍스를 반납합니다.
뮤텍스 사용시의 흐름도는 다음과 같습니다.

1. HANDLE hMutex;
핸들을 하나 선언합니다.

2. hMutex = CreateMutex (
  NULL,     // 디폴트 보안관리자.
  FALSE,    // 누구나 소유 할 수 있는 상태로 생성.
  NULL      // numaned mutex
  );
뮤텍스를 생성합니다.

3. WaitForSingleObject(hMutex, INFINITE);
임계영역 진입직전에 뮤텍스를 획득합니다.

4. ReleaseMutex(hMutex);
임계영역에서 나오자마자 뮤텍스를 반환합니다.

5. CloseHandle(hMutex);
더이상 뮤텍스를 사용할 경우가 없거나, 프로그램 종료시에 뮤텍스를 해제합니다.

아래는 뮤텍스를 사용한 예제입니다.

  1. /*  
  2.     CriticalSectionSyncMutex.cpp  
  3.     프로그램 설명: 크리티컬 섹션과 뮤텍스 비교  
  4. */ 
  5.  
  6. #include <stdio.h>  
  7. #include <windows.h>  
  8. #include <process.h>  
  9. #include <tchar.h>  
  10.  
  11. #define NUM_OF_GATE     6  
  12.  
  13. LONG gTotalCount = 0;  
  14.  
  15. // CRITICAL_SECTION   gCriticalSection;  
  16. HANDLE hMutex;  
  17.  
  18. void IncreaseCount()  
  19. {  
  20. //  EnterCriticalSection (&gCriticalSection);  
  21.     WaitForSingleObject(hMutex, INFINITE);  
  22.  
  23.     gTotalCount++;  
  24.  
  25. //  LeaveCriticalSection (&gCriticalSection);  
  26.     ReleaseMutex(hMutex);  
  27. }  
  28.  
  29.  
  30. unsigned int WINAPI ThreadProc( LPVOID lpParam )   
  31. {   
  32.     for(DWORD i=0; i<1000; i++)  
  33.     {  
  34.         IncreaseCount();  
  35.     }  
  36.  
  37.     return 0;  
  38. }   
  39.  
  40.  
  41. int _tmain(int argc, TCHAR* argv[])  
  42. {  
  43.     DWORD dwThreadIDs[NUM_OF_GATE];  
  44.     HANDLE hThreads[NUM_OF_GATE];  
  45.  
  46. //  InitializeCriticalSection(&gCriticalSection);  
  47.     hMutex = CreateMutex (  
  48.                    NULL,     // 디폴트 보안관리자.  
  49.                    FALSE,    // 누구나 소유 할 수 있는 상태로 생성.  
  50.                    NULL      // numaned mutex  
  51.              );  
  52.  
  53.     if (hMutex == NULL)   
  54.     {  
  55.         _tprintf(_T("CreateMutex error: %d\n"), GetLastError());  
  56.     }  
  57.  
  58.     for(DWORD i=0; i<NUM_OF_GATE; i++)  
  59.     {  
  60.         hThreads[i] = (HANDLE)  
  61.             _beginthreadex (   
  62.                 NULL,  
  63.                 0,                        
  64.                 ThreadProc,                 
  65.                 NULL,                      
  66.                 CREATE_SUSPENDED,            
  67.                 (unsigned *)&dwThreadIDs[i]     
  68.             );  
  69.  
  70.         if(hThreads[i] == NULL)  
  71.         {  
  72.             _tprintf(_T("Thread creation fault! \n"));  
  73.             return -1;  
  74.         }  
  75.     }  
  76.  
  77.     for(DWORD i=0; i<NUM_OF_GATE; i++)  
  78.     {  
  79.         ResumeThread(hThreads[i]);  
  80.     }  
  81.  
  82.  
  83.     WaitForMultipleObjects(NUM_OF_GATE, hThreads, TRUE, INFINITE);  
  84.  
  85.     _tprintf(_T("total count: %d \n"), gTotalCount);  
  86.  
  87.     for(DWORD i=0; i<NUM_OF_GATE; i++)  
  88.     {  
  89.         CloseHandle(hThreads[i]);  
  90.     }  
  91.     
  92. //  DeleteCriticalSection(&gCriticalSection);  
  93.     CloseHandle(hMutex);  
  94.  
  95.     return 0;  
  96. }  
 
Posted by skensita