Skip to content

WindowsApi:CreateThread

Creates a thread to execute within the virtual address space of the calling process. To create a thread that runs in the virtual address space of another process, use the CreateRemoteThread function.

Prototype

Syntax:

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
);

Parameters:

Parameters

IO

Remarks

lpThreadAttributes

in, optional

보안 디스크립터

dwStackSize

in

초기 스텍 크기

lpStartAddress

in

스레드와 연결될 함수포인터

lpParameter

in, optional

스레드와 연결될 함수의 인자

dwCreationFlags

in

생성 옵션

lpThreadId

out, optional

스레드 ID

Requirements:

Header

Winbase.h (include Windows.h)

Library

Kernel32.lib

DLL

Kernel32.dll

함수가 성공하면 새로운 스레드 핸들을 반환하고, 실패할 경우 NULL을 반환하며 오류정보는 GetLastError()를 통하여 알 수 있다. 주의사항으로 스레드를 사용할 경우 Visual Studio의 경우 프로젝트 속성 > 구성 속성 > C/C++ > 코드 생성 > 런타임 라이브러리를 다중스레드로 적용해야 한다.

Simple Example

thread_handle = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)ThreadFunc, NULL, 0, &thread_id);
CloseHandle(thread_handle);

CreateThread WARNING

CreateThread() 사용 경고. Win32 함수 ExitThread()와 CreateThread() 사용은 추천하지 않는다. 일시 중단된 스레드가 C 런타임 데이터 구조에 대한 액세스를 완료할 때까지 둘 이상의 스레드가 대기 상태로 차단되어 있는 경우 SuspendThread()를 사용하면 교착 상태가 발생할 수 있다.

올바른 스레드 종료 방법

스레드를 종료시키기 위한 바람직한 방법에 대하여 아래와 같이 설명한다.

Win32 스레드 함수 비교

CreateThread()
윈도우 API로, 새로운 스레드를 생성한다. (Windows.h)
_beginthread()
C/C++ Runtime-Library (process.h).
새로운 쓰레드를 생성하고 난 후 바로 CloseHandle()를 호출하여 생성한 스레드의 핸들을 닫아버려서 스레드간 통신이 불가능하다. 핸들을 바로 닫는 이유는 Win32의 상세함을 숨기기 위함인데 결국 버그가 되어 버린 함수이다. 짝을 이루는 함수는 _endthread()이며, 생성한 스레드가 종료되면, 이 함수가 자동으로 호출된다. 따라서 이 함수는 명시하지 않으며, 할 경우 에러가 난다. 성공적으로 수행되면 새 스레드를 가리키는 핸들을 반환하고 오류가 있는 경우에는 오류 코드를 반환한다.
_beginthreadex()
C/C++ Runtime-Library (process.h).
내부적으로 새로 생성한 쓰레드의 핸들을 닫지 않기 때문에 명시적으로 _endthreadex()이며, 역시 생성된 스레드가 종료되면 자동으로 호출된다. 따라서 이 함수는 명시하지 않아도 된다. _endthreadex()를 명시해도 _endthread()처럼 에러가 나진 않는다. 성공적으로 수행되면 새 스레드를 가리키는 핸들을 반환하고 오류가 있는 경우에는 오류 코드를 반환한다.

Result

Libcmt.lib로 빌드한 프로그램에서 C 런타임 루틴을 호출하려면 _beginthread() 또는 _beginthreadex()를 사용하여 스레드를 시작해야 한다. Win32 함수 ExitThread()와 CreateThread() 사용은 추천하지 않는다. 그 이유는 #CreateThread WARNING항목 참조.

MSDN 설명

  • 참조: [http://msdn.microsoft.com/ko-kr/library/7t9ha0zh(v=vs.110.aspx MSDN: 스레드 컨트롤을 위한 C 런타임 라이브러리 함수]
  • LIBCMT 및 MSVCRT C 런타임 라이브러리는 스레드를 만들고 종료하기 위해 _beginthread(), _beginthreadex()_endthread(), _endthreadex() 함수를 제공한다. _beginthread()와 beginthreadex()는 새 스레드를 만들고 작업이 성공하면 스레드 식별자를 반환한다. 스레드는 실행을 완료하면 자동으로 종료되거나 _endthread() 또는 _endthreadex()를 호출하여 스스로 종료할 수 있다.
  • 차이점: _beginthread()와 _beginthreadex()는 Win32 API의 CreateThread()와 유사하지만 아래와 같은 차이점이 있다. 이러한 함수는 특정한 C 런타임 라이브러리 변수를 초기화한다. 이것은 스레드에 C 런타임 라이브러리를 사용하는 경우에만 의미가 있다. CreateThread()는 보안 특성을 제어한다. 이 함수를 사용하여 일시 중단된 상태에서 스레드를 시작할 수 있다.
  • _beginthread()와 _beginthreadex() 함수는 새 스레드를 만든다. 스레드는 코드 및 데이터 세그먼트를 한 프로세스의 다른 스레드와 공유하지만 고유한 레지스터 값, 스택 공간 및 현재 명령 주소를 가진다. 시스템은 각 스레드에 CPU 시간을 제공하므로 프로세스의 모든 스레드가 동시에 실행될 수 있다.
  • _endthread() 함수는 _beginthread()에서 만든 스레드를 종료하고, 이와 마찬가지로 _endthreadex() 함수는 _beginthreadex()에서 만든 스레드를 종료한다. 스레드는 작업이 끝나면 자동으로 종료된다. _endthread()와 _endthreadex()는 스레드 내에서 조건 종료에 유용하다. 예를 들어, 통신 포트를 제어할 수 없게 되면 통신 처리 전용 스레드를 종료할 수 있다.

See also

LIBCMT & MSVCRT C

Favorite site