배고픈 개발자 이야기

[C++] Mutex & Semapore & Dead Lock 본문

언어/C언어, C++언어

[C++] Mutex & Semapore & Dead Lock

이융희 2020. 4. 24. 18:20
728x90

프로그래머라면 한번쯤은 들어봤을 것이다.

뮤텍스 / 세마포어 / 데드락등이 있다.

 

그냥 설명만으로는 이해하기가 어려워서 보통 화장실에 많이 비유를 한다..

Mutex는 화장실에서 한줄로 줄을 서서 기다리는 거고, Semapore는 여러줄로 서서 기다리는거야라고 해서

아.. 그럼 Semapore가 효율적이겠네?? 라고 이해했지만 그것은 오산이었다.

 

비유적으로 이해하는것에는 한계가 있다.

테스트가 아닌 실질적인 코드로 보니 확실히 이해되는 부분이 있었다.

 

우선 변기통의 개수는 스레드의 개수를 의미한다는것이다.

그리고 줄서서 기다리는것은 lock을 걸려고하는자 예를들면 client와 같은 개념이고 스레드를 가진 친구는 server라고 이해하면 편하다.. 왜냐하면 client가 보통 서버에 요청을 하니까

 

C++에서 

Mutex 사용시 한줄서기 ( thread = 1개 )

DWORD WaitForSingleObject( HANDLE hHandle, DWORD dwMilliseconds);
// 종료를 기다릴 스레드를 가리키는 핸들, 대기시간
// 성공: WAIT_OBJECT_0 또는 WAIT_TIMEOUT, 실패: WAIT_FAILD

HANDLE hTread = Createthread(...);
WaitForSingleObject(hThread, INFINITE);

한줄서기의 주 사용처는 공유메모리와 같은 자원이 순서대로 자원을 활용해야 할 때 사용하는것으로 보인다.

두 군데서 동시에 바꿨다가는 정상적인 값이 남아있지 않을테니까..

 

Semapore 사용시 여러줄서기 ( thread = 여러개)

DWORD WaitForMultipleObjects(
    DWORD nCount, 
    CONST HANDLE *lpHandles,  
    BOOL fWaitAll, 
    DWORD dwMilliseconds 
); 
// 성공: WAIT_OBJECT_0 ~ WAIT_OBJECT_0 + nCount-1 또는 WAIT_TIMEOUT, 실패: WAIT_FAILED

// 모든 스레드 종료를 기다릴 경우
 HANDLE hThread[2];
 HANDLE hThread[0] = CreateThread(...);
 HANDLE hThread[1] = CreateThread(...);
 WaitForMultipleObjects(2, hThread, TRUE, INFINITE);
 
 // 두 스레드 중 하나의 종료를 기다릴 경우
 HANDLE hThread[2];
 HANDLE hThread[0] = CreateThread(...);
 HANDLE hThread[1] = CreateThread(...);
 DWORD retval = WaitForMultipleObjects(2, hThread, FALSE, INFINITE);
 switch (retval)
 {
 case WAIT_OBJECT_0: // hTread[0] 종료
  break;
 case WAIT_OBJECT_0+1: // hTread[1] 종료
  break;
 case WAIT_FAILED:    // 오류 발생
  break;
 }

semapore는 변기 자리가 하나씩 날때마다 들어가는 케이스도 있고, 여러개가 동시에 비었을 때 들어가는 케이스도 있다. 필요한거에 맞게 쓰도록 하자.

Comments