단막 Windows API
CreateThread로 스레드 생성하기
본 포스팅에서는 CreateThread
를 사용하여 스레드를 생성하는 간단한 예를 정리한다.
새 스레드에서 실행할 프로시저 형식
새 스레드에서 호출할 프로시저의 형식(시그니처)은 다음과 같이 정의한다.
DWORD <NAME>(LPVOID lpParam);
lpParam
매개변수는 CreateThread
함수를 실행할 때 스레드로 전달될 수 있다.
위 형식을 따라 콘솔 창을 열고 1부터 30까지 세는데 1,000 밀리세컨드마다 지연시키는 프로시저를 작성해 보겠다. lpParam
에는 이 스레드를 만든 부모 창 HWND
를 전달한다고 약속한다.
DWORD ThreadProc(LPVOID lpParam) {
HWND hWnd = (HWND)lpParam;
/* 새 콘솔창을 띄운다. */
AllocConsole();
/* 새 콘솔창에 맞추어 표준 입출력 핸들을 다시 연다. */
freopen("CONIN$", "r", stdin);
freopen("CONOUT$", "w", stdout);
freopen("CONOUT$", "w", stderr);
printf("Console Created!\n");
/* 1000 밀리세컨드의 간격을 두고 1부터 30까지 출력한다. */
while (TRUE) {
static int count = 0;
printf("count = %d\n", ++count);
Sleep(1000);
if (count >= 30) break;
}
/* 5000 밀리세컨드의 여유를 두고 콘솔창을 닫는다. */
Sleep(5000);
FreeConsole();
/* 이 스레드를 종료한다. */
return 0;
}
새 스레드 생성 및 실행
CreateThread
의 원형은 다음과 같다.
HANDLE CreateThread(
LPSECURITY_ATTRIBUTES lpThreadAttributes,
DWORD dwStackSize,
LPTHREAD_START_ROUTINE lpStartAddress,
LPVOID lpParameter,
DWORD dwCreationFlags,
LPDWORD lpThreadId
);
매개변수에 대한 자세한 내용은 MSDN을 참조한다. 여기에서는 간략한 사용법만을 보기 위해 각종 보안 코드들은 생략한다. 다음은 가장 간단한 호출법이다. lpStartAddress
(3번째 매개변수)에 앞서 작성한 프로시저를 지정하고, lpThreadId
(마지막 매개변수)에 새로 생성된 스레드의 ID값이 전달된다. 반환되는 값은 생성된 스레드의 핸들(HANDLE
)이다.
hThread = CreateThread(NULL, 0, [PROCEDURE], (LPVOID)[PARAMETER], 0, &[THREAD ID]);
다음은 실제 소스에 작성한 예이다.
LRESULT CALLBACK WndProc(HWND hWnd, UINT uMessage, WPARAM wParam, LPARAM lParam) {
/* 중략 */
switch (uMessage) {
/* 중략 */
case WM_CREATE:
{
/* 창을 생성할 때 스레드도 함께 생성한다. */
HANDLE hThread = NULL;
DWORD dwThreadId = 0;
hThread = CreateThread(NULL, 0, ThreadProc, (LPVOID)hWnd, 0, &dwThreadId);
}
break;
/* 중략 */
}
/* 중략 */
}
실행 결과
프로그램을 실행하면 빈 창과 함께 콘솔창이 출력된다. 콘솔창이 1부터 30까지 세고 닫히는 동안 창에서는 GUI 이벤트를 독립적으로 수행할 수 있다.