본문 바로가기
정리글

Thread관리 - SuspendThread 와 ResumeThread 문제점

by lch831009 2020. 4. 11.

문제점 :

SuspendThread()는 deadlock을 발생시킬 소지가 매우 높은 API이다. 아래와 같은 시나리오에서 절대적으로 deadlock이 발생한다. T1, T2 두개의 Thread가 존재하고, 두개 Thread 모두 printf()를 반복해서 호출한다. T1에서는 주기적으로 T2를 Suspend/Resume한다. 결론적으로 Deadlock이 발생한다. 이유는 T2에서 printf()(* Multi thread환경에서는 printf()에서 내부적으로 Critical Section(CS)을 사용한다)가 호출되고 CS lock이 걸린 상태로 T1이 T2로 SuspendThread()를 호출하면, T2는 printf() 호출이 끝나지 않은 상태, 즉 CS lock이 걸린 상태로 멈추게 되고, T1은 계속해서 printf()를 호출하면 CS lock이 중복해서 발생하는 꼴이 되므로 deadlock이 발생하게 된다. T1은 T2의 printf()호출이 끝나기를 기다리고, T2는 ResumeThread()를 기다리기 때문이다. 

출처: https://techpedia.tistory.com/8 [기술, 그 끝은?]

 

 

Q. 스레드를 일시정지 재시작할때 SuspendThread 와 ResumeThread 써는데 문제가 있어서 질문 드립니다.

일시정지와 재시작은 됩니다. 그런데 문제는 가끔식 프로그램이 멈춰버립니다. 찿아보니 SuspendThread 와 ResumeThread 자체적으로 문제가 있다고 하던데 무슨말인지 모르겟습니다. 어덜게 해결할수 있나요?? 부탁드립니다.

 

 

A1. SuspendThread - ResumeThread를 하기 보단 Event 객체를 하나 생성해서 대기하고 있게 하는게 낫습니다.

Event(혹은 다른 Thread) 에 대해 WaitForSingleObject를 걸면 멈춥니다. (정확힌 멈추는게 아니라 대기)

SuspendThread는 그냥 없는 함수라고 생각하세요.

 

A2. 쓰레드를 어떻게 사용하느냐에 따라 자체적으로 문제가 있는 것 처럼 보일 수도 있죠.
멈췄다 실행했다를 간단히 반복하시려면, 쓰레드 루프안에 코드가 복잡하지 않다면.


BOOL m_bRun = FALSE;
while(1)
{
    if(!m_bRun)
    {
        continue;
    }
    ....
    ..........
    .............
}

 

와 같이 사용하세요. 커널오브젝트를 사용하여 제어 하시려면 MFC 에서 제공되는 WinThread 보다는  Win32 C API 쓰레드를 사용하시는 게 낳습니다.