2010년 11월 28일 일요일

[Win32] _beginthreadex()와 CreateThread()의 사용

* _beginthreadex()
 ; Win32용 API로 원래 CreateThread()가 있지만 이 함수는 완전히 Win32용 API와의 호환성을 지원하는 목적으로 만들어졌기 때문에 윈도우의 서브 시스템의 하나인 POSIX와 호환성을 보장하지 못한다. 그래서 윈도우에서는 POSIX C/C++ 라이브러리와 호환성을 보장하기 위해 '_beginThreadex()'함수를 지원한다.

*_beginthreadex() 사용시 에러 해결
- '_beginthreadex' : undeclared identifier
- 'unresolved external symbol'
 => 비주얼 스튜디오 6.0에서는 단일 스레드 라이브러리 상태가 기본적으로 설정되어있기 때문에 위와 같은 에러 발생시 다음과 같이 설정해본다.

> Project - Settings


- Category => Code Generation
- USE run-time library -> Multithreaded DLL


* CreateThread()와 _beginThreadex()의 형식 비교

#include <windows.h>
HANDLE CreateThread(                                                              //리턴 타입 HANDLE (void*)
             LPSECURITY_ATTRIBUTES lpThreadAttributes,        //보안 디스크립터(구조체)
             SIZE_T dwStackSize,                                                        //초기 스택 사이즈 (unsigned long)
             LPTHREAD_START_ROUTINE lpStartAddress,           //스레드 함수 모듈 (반환형 DWORD)
             LPVOID lpParameter,                                                      //스레드 인자 (void*)
             DWORD dwCreationFlags,                                              //생성 옵션 (unsigned long)
             LPDWORD lpThreadID                                                       //스레드 ID (unsigned long*)
);
 => 주로 인자의 자료형이 DWORD(unsigned long)이다.


#include <process.h>
unsigned long _beginthreadex(                                        //리턴 타입 unsigned long
             void* security,                                                          //보안 변수 (void*)
              unsigned stack_size,                                               //초기 스택 사이즈 (unsigned int)
              unsigned (*start_address)(void*),                     //스레드 함수 모듈 (반환형 UINT)
              void* arglist,                                                             //스레드 인자 (void*)
              unsigned initflag,                                                     //생성 옵션 (unsigned int)
              unsigned* thrdaddr                                                 //스레드 ID (unsigned int*)
);
 => 주로 인자의 자료형이 unsigned int 타입이다. (int는 생략 가능하므로...) 윈도우에서는unsigned int를 UINT로 매크로 정의하고 있다. 두 함수의 인자를 비교해보면 아무 형식이나 입력 가능해야 하는 스레드 인자를 제외하고는 모두 데이터 타입이 다르다. 그리고 애시당초 헤더 파일도 다르다...


그럼 간단한 스레드 생성의 예를 보자.
- CreateThread()...의 경우
#include <windows.h>
                    ...
DWORD WINAPI ThreadFunc(void *arg)
{
     //스레드 구현
}
                   ...
HANDLE hThread;
DWORD dwThreadID;
                   ...{
     hThread = CreateThread(NULL, 0, ThreadFunc, NULL, 0, &dwThreadID);             //스레드 생성
}
                   ...
=> 스레드 함수의 리턴 타입(DWORD), 스레드ID(DWORD)의 데이터 타입을 유의하자.


- _beginthreadex()...의 경우
#include <process.h>
                ...
UINT WINAPI ThreadFunc(void *arg)
{
      //스레드 구현
}
                ...
HANDLE hThread;
UINT dwThreadID;
                ...
{
     hThread = (HANDLE)_beginthreadex(NULL, 0, ThreadFunc, NULL, 0, &dwThreadID);
}                ...
=> CreateThread()와 데이터 타입이 다르므로 주의한다스레드의 리턴 타입(UINT), _beginthreadex()의 리턴 타입은 HANDLE 타입이 아니므로 타입 캐스팅을 해야한다. 그리고 스레드ID의 타입(UINT)을 유의해야한다.

댓글 없음:

댓글 쓰기