커널 오브젝트의 상태

1. Mutex 기준으로…
    - signaled상태 -> 소유가 가능한 상태.
    - non-signaled 상태 -> 이미 소유되어진 상태.

2. Semaphore 기준으로…
    - signaled상태 -> 세마포어 카운트가 0이 아닌 경우.
    - non-signaled 상태 -> 세마포어 카운트가 0인 경우.

커널 오브젝트 동기화 기법 1 (Mutex)

  1. HANDLE CreateMutex(    
  2.                   LPSECURITY_ATTRIBUTES lpMutexAttributes, // SD    
  3.                   BOOL bInitialOwner,            // initial owner(false for signaled)    
  4.                  LPCTSTR lpName              // object name    
  5. );   
  6.   
  7. BOOL ReleaseMutex(    
  8.              HANDLE hMutex      // non-signaled -> signaled    
  9. );    
  10.   
  11. BOOL CloseHandle( HANDLE hObject // handle to object );  

사용자 삽입 이미지


 

뮤텍스 프로그래밍 순서도를 말씀드리겠습니다.

1. CreateMutex - 뮤텍스 생성
2. _beginthreadex - 쓰레드 생성
3. 쓰레드 루프
    - WaitForSingleObject(hMutex) - 뮤텍스 받음
    - ReleaseMutex - 뮤텍스 반환
4. WaitForSingleObject(hThread) - 쓰레드 종료를 기다림
5. CloseHandle(hMutex) - 뮤텍스 소멸


커널 오브젝트 동기화 기법 2 (Semaphore)

세마포어의 특징
 - 세마포어가 0이 되어야 세마포어 오브젝트가 non-signaled 상태가 된다.

  1. HANDLE CreateSemaphore(    
  2.     LPSECURITY_ATTRIBUTES lpSemaphoreAttributes,    // SD    
  3.     LONG lInitialCount,                 // initial count    
  4.     LONG lMaximumCount,             // maximum count    
  5.     LPCTSTR lpName                              // object name    
  6. );   
  7.   
  8. BOOL ReleaseSemaphore(    
  9.              HANDLE hSemaphore,                 // handle to semaphore    
  10.              LONG lReleaseCount,                // count increment amount    
  11.              LPLONG lpPreviousCount                 // previous count    
  12. );   
  13.   
  14. BOOL CloseHandle( HANDLE hObject // handle to object );  



세마포어 프로그래밍 순서도를 말씀드리겠습니다.

1. CreateSemaphore - 세마포어 생성
2. _beginthreadex - 쓰레드 생성
3. 쓰레드 루프
    - WaitForSingleObject(hSem) - 세마포어 받음
    - ReleaseSemaphore - 세마포어 반환
4. WaitForSingleObject(hThread) - 쓰레드 종료를 기다림
5. CloseHandle(hSem) - 세마포어 소멸

뮤텍스와 구성은 똑같습니다만,
뮤텍스는 현재 소유권을 가진(점유중인) 쓰레드만이 뮤텍스 반환의 권한을 가집니다.
반면, 세마포어는 현재 소유권을 가진 쓰레드가 아니더라도,
ReleaseSemaphore 함수로 누구든지 세마포어를 반환할 수있습니다.
결국 소유권의 차이입니다.

그리고 제가 MFC 를 공부했을 때에도 뮤텍스와 세마포어가 있었습니다.
MFC 세마포어는 특정영역을 수행하는 쓰레드의 개수를 지정할 수 있습니다.
특정영역을 한 번에 하나의 쓰레드만 접근하는 것이 아니라,
여러개의 세마포어를 둘 수 있었구요.


커널 오브젝트 동기화 기법 3 (Event)

Event의 특징
 - auto & manual–reset 모드의 커널 오브젝트의 생성이 가능하다.

  1. HANDLE CreateEvent(    
  2.     LPSECURITY_ATTRIBUTES lpEventAttributes,     // SD    
  3.     BOOL bManualReset,                 // reset type, TRUE for manual-reset   
  4.     BOOL bInitialState,                // initial state, TRUE for signaled state    
  5.     LPCTSTR lpName                 // object name    
  6. );   
  7.   
  8. BOOL ResetEvent(    
  9.     HANDLE hEvent       // handle to event, to non-signaled Event   
  10. );  


사용자 삽입 이미지


 

Event 는 위의 뮤텍스와 세마포어와는 구분되는 독자적인 특징을 가집니다.
바로, Non-signaled 에서 Signaled 상태로 바뀔 때,
대기중인 모든 쓰레드를 동시에 깨운다는 것이져.

1. CreateEvent - 이벤트 생성
2. _beginthreadex - 쓰레드 생성
3. 쓰레드 루프
    - WaitForSingleObject(hEvent) - 이벤트 받음
(SetEvent - 이벤트 non-signaled -> signaled 전환)
(ResetEvent - 이벤트 signaled -> non-signaled 전환)
4. WaitForSingleObject(hThread) - 쓰레드 종료를 기다림
5. CloseHandle(hEvent) - 이벤트 소멸

이번 예제는 코드가 많은 관계로 아래의 소스코드를 첨부합니다.
출처는 역시 윤성우 선생님의 TCP/IP 프로그래밍입니다.




[출처] http://thx4alice.tistory.com/85

Posted by 몽센트