LISTORY
[윈도우즈 시스템 프로그래밍] 커널 모드 동기화(1) 본문
뇌를 자극하는 윈도우즈 시스템 프로그래밍 책 관련 유투브 강의 정리이다.
오늘 정리할 내용은 커널 모드 동기화 부분이다.
YouTube 강의 주소 : 커널 모드 동기화(1)
커널 모드 동기화
이번 시간엔 세마포어 동기화 기법, 뮤텍스 동기화 기법에 대해 공부할 건데,
그전에 우선 세마포어, 뮤텍스 이 두가지의 특성부터 설명하고 사용방법을 설명하도록 하겠다.
운영체제 책에서 설명하는 세마포어는 동기화 기법의 이름이다.
그리고 이 세마포어 중에서 바이너리 세마포어를 뮤텍스라고 한다.
즉, 세마포어가 있고 세마포어의 일부로서 뮤텍스 존재하는 것이다.
세마포어는 세마포어가 있고 뮤텍스도 있지만, 윈도우즈에서는 이 각각을 기법 이름으로 가져다 쓴다.
운영체제에서 이야기하는 세마포어와 유사한 기법이 세마포어 기법이고
그중에 일부로서 존재하는 뮤텍스라는 기법의 특성을 그대로 살린 것이 윈도우즈에서 뮤텍스 기법이다.
⊙ 세마포어와 뮤텍스의 차이
임계 영역에 진입하기 위해서는 키를 얻어야 한다.
세마포어와 뮤텍스의 가장 큰 차이는 세마포어는 키가 다수 존재하고, 뮤텍스는 하나의 키만 존재한다는 것이다.
세마포어는 임계영역에 들어오는 쓰레드의 갯수를 제한할 수 있다.
뮤텍스는 키가 하나이기 때문에 하나의 쓰레드만 들어올 수 있다.
⊙ 뮤텍스(Mutex)의 생성
뮤텍스라는 열쇠를 생성하는 함수이다.
HANDLE CreateMutex(
LPSECURITY_ATTRIBUTES lpMutexAttributes, // 보안 설정
BOOL bInitialOwner, // 소유자 지정(TRUE, FALSE)
LPCTSTR lpName // 뮤텍스 이름 지정
);
이는 커널모드 동기화 기법이기 때문에 커널 오브젝트 생성을 동반시킨다.
각각을 설명하자면,
보안 설정 : 핸들테이블 키가 상속 가능?
소유자 지정 : 열쇠를 만든 사람이 초기에 소유할 수 있도록 할 것이냐, 아니면 누구나 소유 가능하도록 할 것인가
뮤텍스 이름 지정 : 뮤텍스는 이름을 지정할 수 있다. 이는 나중에 자세히 설명하겠다.
⊙ 뮤텍스를 통한 동기화 방법
WaitForSingleObject()를 통해 뮤텍스를 획득하고 ReleaseMutex()를 통해 반납한다.
유저모드 동기화의 경우 함수의 기능을 설명하지 않았지만, 여기서는 함수의 역할을 아는 것이 훨씬 도움된다.
뮤텍스를 커널 오브젝트라 생각하자.
WaitForSingleObject() 함수를 벗어나기 위해서는 뮤텍스가 Signaled 상태여야 한다.
ReleaseMutex() 함수는 키를 Signaled 상태로 바꾸어 주는 함수이다.
WaitForSingleObject() 함수는 키를 Signaled 상태에서 벗어나면서 다시 Non-Signaled 상태로 바꾼다.
어떠한 쓰레드가 키를 가지고 WaitForSingleObject() 함수를 호출했다.
현재 뮤텍스가 Signaled 상태라 하면, 쓰레드는 임계영역으로 진입이 되며 뮤텍스를 Non-Signaled 상태로 바꾼다.
WaitForSingleObject()는 뮤텍스가 Signaled 상태가 되야 빠져나갈 수 있으므로,
뮤텍스가 Non-Signaled 상태가 되면,두번째 쓰레드는 WaitForSingleObject() 함수를 빠져나올 수 없다.
그럼 WaitForSingleObject() 함수는 뮤텍스가 다시 Signaled 상태가 될때까지 기다린다.
대기중인 쓰레드는 뮤텍스가 다시 Signaled 상태가 될때까지 기다린다.
앞서 들어간 쓰레드는 임계영역을 나오면서 ReleasMutex()를 호출하고, 이후 Mutex는 다시 Signaled 상태가 된다.
그럼 WaitForSingleObject() 함수가 호출되면서 대기중에 있던 쓰레드는 WaitForSingleObject()를 반환하며 임계영역에 진입이 가능하다.
즉, 뮤텍스의 Signaled, Non-Signaeld 상태를 이용하며 임계 영역을 이용한다.
⊙ 세마포어의 생성
HANDLE CreateSemaphore(
LPSECURITY_ATTRIBUTES lpSemaphoreAttributes,
LONG lInitialCount, // 세마포어의 카운트, 열쇠의 개수(값)
LONG lMaximumCount,
LPCTSTR lpName
);
lInitialCount : 세마포어의 초기값 결정
lMaximumCount : 세마포어가 가질 수 있는 카운트의 최대값. lInitialCount와 같거나 커야한다.
⊙ 세마포어 기반의 동기화
세마포어 카운트가 10이다. 그럼 열쇠의 개수가 10이라는 것이다.
ReleasSemaphore()가 호출될 경우, 세마포어 카운트 값이 하나가 증가된다.
WaitForSingleObject()가 호출될 경우, 세마포어 카운트의 값이 하나 감소된다.
세마포어 카운트 값이 0이 되지 않는 한, WaitForSingleObject() 함수가 호출되도 블러킹 상태가 되지 않는다.
즉, Non-Signaled 상태로 되지 않는다.
세마포어 카운트가 현재 10이기 때문에 WaitForSingleObject()를 총 10개의 쓰레드가 진입이 가능하다는 것이다.
그 이후에 호출되는 쓰레드는 블러킹상태가 된다.
즉, 총 10개의 쓰레드가 동시에 임계영역에 접근 가능하다.
만일, 세마포어의 lMaximumCount를 1로 둔다면, 뮤텍스와 동일한 특성을 갖는다.
'IT > 윈도우 프로그래밍' 카테고리의 다른 글
[윈도우즈 시스템 프로그래밍] 실행 순서에 있어서의 동기화 (0) | 2018.09.21 |
---|---|
[윈도우즈 시스템 프로그래밍] 커널 모드 동기화(2) (0) | 2018.09.16 |
[윈도우즈 시스템 프로그래밍] 유저 모드 동기화 (0) | 2018.09.16 |
[윈도우즈 시스템 프로그래밍] 쓰레드 동기화 기법1 (0) | 2018.09.03 |
[윈도우즈 시스템 프로그래밍] 2부 정리 (4) (0) | 2018.09.02 |