LISTORY
[윈도우즈 시스템 프로그래밍] 커널 모드 동기화(2) 본문
뇌를 자극하는 윈도우즈 시스템 프로그래밍 책 관련 유투브 강의 내용 정리이다.
저번 시간에 이어 커널 모드 동기화 부분을 설명하겠다.
YouTube 강의 주소 : 커널 모드 동기화(2)
커널 모드 동기화
⊙ 이름있는 뮤텍스 기반의 프로세스 동기화
이번 강의는 알면 좋지만 몰라도 크게 상관없는 내용이라고 한다...
프로세스 A, 프로세스 B 존재하고, 쓰레드가 각각의 프로세스에 또 존재한다.
이 쓰레드들이 동기화가 가능할까? 결론은 가능하다.
상황을 만들어 보자.
동기화를 위해 뮤텍스 하나를 공유하는 것이 의미가 있다.
프로세스 A가 뮤텍스 생성하였다.
프로세스 A에서 생성된 뮤텍스는 당연히 프로세스 A 내에 있는 쓰레드에게 접근이 가능하다.
여기서 프로세스 B의 쓰레드와 동기화가 가능하려면 프로세스 B에 있는 쓰레드도 뮤텍스에 접근이 가능해야 하는데, 이는 불가능하다.
204라는 핸들 주소만 넘겨주면 된다? 절대 안된다. 핸들 주소는 해당 프로세스 내에서만 의미가 있기 때문이다.
즉, 프로세스 B에는 이 뮤텍스에 대한 정보를 알 수 없다..
그럼 동기화를 하려면 어떻게 해야할까?
동기화가 된다는 가정 하에서 A 프로세스에 저장된 쓰레드의 핸들 테이블 정보가 프로세스 B 의 쓰레드의 핸들테이블 정보가 등록되어야 한다.
하나의 프로세스 내에 존재하는 쓰레드들 간의 동기화를 할 때엔 핸들을 이용했다.
하지만 현재 상황은 뮤텍스의 핸들을 직접 얻을 수 없다.
그럼 프로세스 B는 뮤텍스를 찾아야 하는데, 이때 뮤텍스의 이름을 사용하여 찾는다.
저번 강의에서 뮤텍스를 생성할 때 뮤텍스의 이름을 지정할 수 있는 부분이 있었다.
여기서 이름을 줄 경우, 이름있는 뮤텍스라고 한다.
이는 세마포어도 마찬가지이다.
이 이름을 통해 자신과 다른 영역에 있는 쓰레드들과도 동기화가 가능하다.
즉, 이름을 통해서 뮤텍스를 등록하면 된다.
뮤텍스의 이름을 사용하여 뮤텍스를 사용하기 위해선 OpenMutex()라는 함수를 사용하면 된다.
예제 코드를 보겠다.
int _tmain(int argc, TCHAR* argv[])
{
if 0
hMutex = CreateMutex(
NULL,
FALSEM
_T("NamedMutex)
);
#else
hMutex = OpenMutex(
MUTEX_ALL_ACCESS,
FALSE,
_T("NamedMutex")
);
#endif
If(hMutex == NULL)
{
_tprintf(_T("CreateMutex error: %d\n), GetLastError());
return -1;
}
ProcessBaseCriticalSectioni();
...
}
이 예제는 전처리기를 사용하여 CreateMutex, OpenMutex를 둘 다 이용하면 된다.
⊙ 뮤텍스의 소유와 WAIT_ABANDONED
소유의 관점에서 세마포어와 뮤텍스의 차이점은?
예제를 살펴보겠다.
void ProcessBaseCriticalSection()
{
dwWatiResult = WatiForSingleObject(hMutex, INFINITE);
switch(dwWaitResult)
{
// 쓰레드가 뮤텍스를 소유하였다.
case WAIT_OBJECT_0:
_tprintf(_T("thread got mutex! \n));
break;
// TIME-OUT이 발생하였다.
case WAIT_TIMEOUT:
_tprintf(_T("time out! \"));
return;
// 뮤텍스 반환이 적절히 이루어지지 않았다.
case WAIT_ABANDONED:
return;
}
....
}
각각의 반환에 대한 케이스가 있는데, 반환이 적절히 이뤄지지 않았을 경우 케이스가 있다.
이걸 설명하기 앞서 세마포어와 뮤텍스에 대해 설명하겠다.
뮤텍스의 경우, 쓰레드 A,B가 있을 때 키를 A가 가지면 A가 반환해야 한다.
A라는 쓰레드가 열쇠를 얻었다.
즉, 임계영역에 있고, B는 대기중이다.
이 상태에서 A 쓰레드가 열쇠를 반환하고 빠져나가야 하는데, 이 쓰레드가 임계영역 안에서 종료되어 버렸다.
이럴 경우, B 쓰레드가 WaitForSingleObject()를 빠져나오면서 반환값으로 WAIT_ABANDONED 값을 갖게된다.
이는 에러를 뜻하는게 아니다.
정상적이지 않은 종료에 의해 뮤텍스를 얻지 못했으므로 이 열쇠를 OS가 B 쓰레드에게 다시 주겠다라는 뜻이다.
세마포어는 카운트 값으로 공유하기 때문에 이러한 소유의 개념이 없다.
'IT > 윈도우 프로그래밍' 카테고리의 다른 글
[윈도우즈 시스템 프로그래밍] 이벤트(Event) 더하기 뮤텍스(Mutex) (0) | 2018.09.21 |
---|---|
[윈도우즈 시스템 프로그래밍] 실행 순서에 있어서의 동기화 (0) | 2018.09.21 |
[윈도우즈 시스템 프로그래밍] 커널 모드 동기화(1) (0) | 2018.09.16 |
[윈도우즈 시스템 프로그래밍] 유저 모드 동기화 (0) | 2018.09.16 |
[윈도우즈 시스템 프로그래밍] 쓰레드 동기화 기법1 (0) | 2018.09.03 |