티스토리 뷰

MFC 스레드 동기화 - 예외처리

CSingleLock, CMultiLock 클래스는 스레드 동기화 클래스를 편리하게 사용할 수 있도록 보조하는 역활

1. CSingleLock

Lock()을 호출하여 뮤텍스 객체를 소유한 스레드가 실행 중 예외 상황이 발생하여 종료하게 되면, Unlock() 이 호출되지 못하는 문제가 발생한다.

1
2
3
4
5
6
7
CMutex g_mutex(...);
MyThread()
{
    g_mutex.Lock();
    // 예외 상황 발생
    g_mutex.Unlock();
}
cs

이런 경우, 아래 코드와 같이 변수 lock 이 스택에 생성되므로 예외 상황이 발생하여 스레드가 종료하게 되면 자동으로 lock의 소멸자가 호출되고, 소멸자에서는 unlock()을 호출한다. 즉, Lock() 이 호출되면 unlock()이 반드시 호출된다는 것이 보장되는 것이다. 이 같은 기법은 뮤텍스 이외에 임계 영역, 세마포, 이벤트에도 모두 적용할 수 있다.

1
2
3
4
5
6
7
8
CMutex g_mutex(...);
MyThread()
{
    CSingleLock lock(&g_mutex);
    g_mutex.Lock();
    // 예외 상황 발생
    g_mutex.Unlock();
}
cs

 

2. CMultiLock

하나의 스레드가 여러 개의 동기화 객체를 사용하는 경우, 각 동기화 객체에 대해 동시에 Lock() 을 호출해야 하는 경우가 발생한다. 이 경우 CMultiLock 객체를 사용하면 하나 또는 모든 동기화 객체가 사용 가능한지 여부를 판단할 수 있다.

예로, 다음 코드는 3개의 이벤트 객체가 모두 신호 상태가 되기를 대기하는 것을 보여준다.

1
2
3
4
5
6
7
8
CEvent g_event[3];
CSyncObject* g_pSyncObjects[3= { &g_event[0], &g_event[1], &g_event[2] };
MyThread()
{
    CMultiLock multilock(g_pSyncObjects, 3);
    multilock.Lock();
    ...
}
cs

3개의 이벤트 객체 중 하나가 신호 상태가 되기를 대기하려면 CMultiLock::Lock() 호출 방법을 다음과 같이 변경한다.

 

1
2
3
4
5
6
7
8
CEvent g_event[3];
CSyncObject* g_pSyncObjects[3= { &g_event[0], &g_event[1], &g_event[2] };
MyThread()
{
    CMultiLock multilock(g_pSyncObjects, 3);
    multilock.Lock(INFINITE, FALSE);
    ...
}
cs

CMultiLock 은 뮤텍스, 이벤트, 세마포 객체를 혼합하여 사용할 수 있으나,
임계 영역 객체에 대해서는 사용할 수 없다는 점에 주의해야 한다.

공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/12   »
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30 31