보통 Win32 API를 이용해서 thread 생성할 때 CreateThread()를 사용한다. 그러나 C run-time library를 사용할 때는 _beginthread()나 _beginthreadex()를 사용해야 한다. MSDN (http://msdn.microsoft.com/en-us/library/7t9ha0zh(v=vs.71).aspx) 에 이 내용이 설명되어 있다. 여기서 중요한 점은 thread 내에서 C run-time library를 사용하는 데 CreateThread()를 사용하면 리소스 누수가 발생한다는 것이다. 이는 프로그램 로직 상에는 아무 문제도 없는 데 메모리 누수(leak)등 쥐도 새도 모르는 문제점이 발생할 수 있다는 것이다.

CreateThread()를 사용했던 코드라면 _beginthreadex()를 사용하는 것이 좋다. 그러나 시작 루틴의 주소등 몇 가지 파라미터가 정확하게 일치하지 않아서 형변환을 시켜줘야 한다. 다음은 CreateThread()와 _beginthreadex()의 기본형이다.

HANDLE WINAPI CreateThread(
  __in_opt   LPSECURITY_ATTRIBUTES lpThreadAttributes,  
  __in       SIZE_T dwStackSize,  
  __in       LPTHREAD_START_ROUTINE lpStartAddress,  
  __in_opt   LPVOID lpParameter,  
  __in       DWORD dwCreationFlags,  
  __out_opt  LPDWORD lpThreadId
);

uintptr_t _beginthreadex( // NATIVE CODE
   void *security,
   unsigned stack_size,
   unsigned ( __stdcall *start_address )( void * ),
   void *arglist,
   unsigned initflag,
   unsigned *thrdaddr 
);
thread를 종료할 때에도 주의할 점이 있다. _beginthread()는 그냥 thread 루틴에서 리턴을 하면 자동으로 _endthread()가 호출되고 thread 루틴에서 사용되었던 자원들도 반환된다.
_beginthreadex()로 시작된 thread는 thread 루틴에서 리턴하면 자동으로 _endthreadex()가 호출되고 자원이 반환된다. 그러나 _beginthreadex()가 호출될 때 생성된 thread HANDLE은 반환되지 않는다. 따라서 CloseHandle()을 호출하여 명시적으로 닫아줘야 한다.

예제 코드는 MSDN의 http://msdn.microsoft.com/en-us/library/kdzttdcb.aspx 페이지를 참고한다.

신고

'프로그래밍' 카테고리의 다른 글

CPU 정보를 어떻게 알 수 있을까?  (0) 2010.04.23
Win32 API Multithreading 시 주의점  (0) 2010.04.20
top

Write a comment





티스토리 툴바