본문 바로가기
프로그래밍

스레드 생성 이후에 언제 Handle을 반환해야 할까?

by bantomak 2024. 8. 7.

스레드를 생성하고 반환받은 Handle 언제 반환해야 할까?

스레드를 생성하고 나면 스레드에 대한 Handle을 반환받는다. 그리고 스레드 객체를 다 사용하고 나면 해당 핸들을 ::CloseHandle() 매소드를 통해서 반환한다.

 

그런데 IOCP 소켓 프로그래밍 관련으로 공부하다가 해당 예제를 발견했다.

쓰레드를 생성하고 받은 hThread 핸들을 생성하자마자 바로 아래에서 ::CloseHandle() 매소드로 바로 반환한다.

 

//클라이언트로부터 문자열을 수신함.
hThread = ::CreateThread(NULL,	//보안속성 상속
    0,				//스택 메모리는 기본크기(1MB)
    ThreadComplete,	//스래드로 실행할 함수이름
    (LPVOID)NULL,	//
    0,				//생성 플래그는 기본값 사용
    &dwThreadID);	//생성된 스레드ID가 저장될 변수주소

::CloseHandle(hThread);

 

여기서 드는 나의 의문은

  • Handle을 바로 반환해도 문제없는가?
  • Handle을 생성 이후 바로 반환하는 게 일반적인 문법인가?

 

스택오버플로우를 참고하자면 오히려 바로 핸들을 닫는 것이 핸들 누수를 막는 방법이라고 설명한다.

스레드 생성 이후에 다른 곳에서 필요한 게 아니라면 바로 Handle을 반환하도록 하자.

 

스레드에 대한 수명은 운영체제가 관리한다. 바로 참조 카운트 방식의 Usage Count라는 필드가 존재하며, 이는 커널 오브젝트 내에서 관리한다. 이 방식은 자원을 참조하는 대상의 수를 계속 추적하고 있다가 아무도 참조하지 않으면, 즉 참조 카운트가 0이 되면 필요 없는 자원이라고 판단하여 지우는 방식이다.

 

우리가 스레드를 생성하면 Usage Count가 2가 된다. 생성된 스레드(+1)와 해당 스레드를 생성해 준 부모 스레드(+1)에 대한 카운트가 적용된다.

 

생성된 스레드가 종료되면 알아서 참조 카운트가 1 감소하게 된다. 그리고 메인 스레드에서 CloseHandle() 메서드를 사용해서 핸들을 닫으면 참조 카운트가 1 감소한다. 그러면 참조 카운트가 0이 되면서 운영체제가 해당 스레드를 제거한다. 때문에 스레드 생성 시 반환된 핸들을 꼭 닫아줘야 한다.

 

참고 사이트

 

스레드가 종료되기 전에 CloseHandle()를 호출해도 된다.

_beginthreadex() 함수를 이용해 스레드를 성공적으로 생성하면 핸들을 반환한다. 그리고 생성한 스레드가 종료되면 CloseHandle 함수를 통해 핸들을 닫아야 한다는 걸 알고 있었다. 아래는 MSDN의 CloseHan

woo-dev.tistory.com

 

Is it reasonable to call CloseHandle() on a thread before it terminates?

I'd like to just create a thread, then call CloseHandle immediately and let the thread die on its own so that I don't have to do extra clean-up work in the 'original' thread (not that cleanup is ha...

stackoverflow.com

댓글