스레드를 생성하고 반환받은 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이 되면서 운영체제가 해당 스레드를 제거한다. 때문에 스레드 생성 시 반환된 핸들을 꼭 닫아줘야 한다.
참고 사이트
'프로그래밍' 카테고리의 다른 글
window 환경에서 NGINX 설치하고 실행하기 (0) | 2024.08.26 |
---|---|
스핀락(Spin Lock)에 대해서 알아보자 (0) | 2024.08.13 |
Base64 인코딩이란? (3) | 2024.07.24 |
단일 장애 지점(SPOF)에 대해서 (1) | 2024.04.29 |
깃허브 코파일럿(GitHub Copliot) 무료로 사용해보기 (0) | 2024.04.25 |
댓글