해당 내용들은 김상형 저자님의 윈도우즈 API 정복 #2 에 나오는 내용들입니다.

(API의 바이블이라고 생각하는 도서이며 옆에 껴두고 필요한 부분들을 참고하면서 공부하기 정말 좋은 책입니다.)

 

한 프로그램에서 여러 가지 작업을 동시에 수행해야 할 경우가 있다.

대체로 cpu가 하나뿐이며 폰 노이만형 컴퓨터는 한 번에 하나의 일만 할 수 있으므로 실제로 이것은 불가능하다.

그리하여 나온 것이 Thread 개념이며 여러 Thread들이 번갈아 가면서 조금씩 작업을 함으로써 동시에 실행되는 듯한

효과를 낼 수 있다.

 

Thread는 프로세스 내에 존재하는 일련의 실행 코드이다.

프로세스는 단지 존재하기만 하는 껍데기일 뿐이며 실제 작업은 스레드가 담당한다.

프로세스 생성 시 하나의 주 스레드가 생성되며 대부분의 경우 주 스레드가 모든 작업을 처리하고 주 스레드가 종료되면

프로세스도 같이 종료된다.

 

스레드가 여러개 생긴 경우라면, 주 스레드와 나머지 스레드들은 CPU 시간을 우선 순위에 따라 적절하게 분배하여 동시에

실행된다. 운영체제는 스레드별로 골고루 CPU 시간을 배분하므로 한 스레드가 시간을 지나치게 오래 끌더라도 다른 스레드가

이에 영향을 받지 않고 실행된다.

그러므로 이 방법은 타이머나 PeekMessage를 사용하는 방법보다 반응성이 훨씬 좋다.

 

하나의 운영체제에 여러 개의 프로세스가 동시에 실행되는 환경을 멀티 태스킹이라하며 하나의 프로세스에서 여러 개의 스레드가

동시에 실행되는 환경은 멀티스레드라 한다.

 

<간단한 Thread 생성 코드>

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
LRESULT CALLBACK WndProc(HWND hWnd,UINT iMessage,WPARAM wParam,LPARAM lParam)
{
    DWORD ThreadID;
    HANDLE hThread;
 
    switch(iMessage) 
    {
    case WM_CREATE:
        hWndMain = hWnd;
        hThread = CreateThread(NULL,0,ThreadFunc, NULL0&ThreadID);
        CloseHandle(hThread);
        return TRUE;
    case WM_DESTROY:
        PostQuitMessage(0);
        return 0;
    }
    return(DefWindowProc(hWnd,iMessage,wParam,lParam));
}
 
cs

 

우선 상기 코드는 주 스레드의 WM_CREATE에서 스레드를 하나 생성한 코드이며 CreateThread 함수를 사용한다.

 

<CreateThread 함수>

1
2
3
4
5
6
7
8
9
10
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
    );
cs

 

 · Parameter 1 (LPSECURITY_ATTRIBUTES lpThreadAttributes)

 

  - 스레드의 보안 속성을 지정하는데 자식 프로세스로 핸들을 상속하지 않는 한 NULL로 지정하면 된다.

 

 · Parameter 2 (SIZE_T dwStackSize)

 

  - 스레드의 스택 크기를 지정하는데 스레드끼리 상호 안정된 동작을 하기 위해 스레드별로 별도의 스택이 할당된다.

  - 스택의 크기를 0으로 지정하면 주 스레드와 같은 크기를 가진다.

 

 · Parameter 3 (LPTHREAD_START_ROUTINE lpStartAddress)

 

  - 스레드의 시작 함수(Entry Point)를 지정하며 실질적으로 가장 중요한 인자. (주 스레드의 WinMain 함수에 해당)

  - 지정된 함수로부터 스레드의 실행을 시작하며 해당 함수가 종료되면 스레드도 종료된다.

  - 시작 함수는 다음과 같은 원형을 가져야 한다. → DWORD WINAPI ThreadFunc(LPVOID lpParameter);

 

 · Parameter 4 (LPVOID lpParameter)

  

  - Parameter 3에서 지정한 스레드의 시작 함수는 LPVOID형의 인수 하나만 받아들이는데 이 인수는 CreateThread의

    네 번째 인수로 지정한다.

  - 4 번째 인수는 스레드로 전달할 작업 내용을 지정한 것이며, 전달할 내용이 없다면 NULL을 전달하면 된다.

 

 · Parameter 5 (DWORD dwCreationFlags)

 

  - 생성할 스레드의 특성을 지정하는 인자이며 아무 특성이 없는 보통 스레드를 만들고자 한다면 0으로 지정하면 된다.

  - 만약 스레드를 만들기만 하고 실행은 하지 않게 하고 싶다면, CREATE_SUSPENDED 플래그를 지정하면 된다.

 

 · Parameter 6 (LPDWORD lpThreadId)

 

  - CreateThread 함수가 스레드를 만든 후 스레드의 ID를 리턴하기 위한 출력용 인수이므로 DWORD형의 변수를 하나
    선언한 후 주소값을 넘겨준다.

 

CreateThread 함수는 스레드를 만든 후 스레드의 핸들을 리턴하며 에러가 발생했을 경우 NULL을 리턴한다.

리턴된 핸들을 이용하여 스레드를 제어하는데 상기 예제는 생성 후 스레드를 제어하지 않기 때문에 바로 핸들을 닫았다.

스레드 핸들과 스레드 자체는 다르므로 핸들을 닫는다고 해서 스레드가 종료되는 것은 아니다.

'Programming > Thread' 카테고리의 다른 글

[API] Thread 6 (동기화 - 크리티컬 섹션)  (0) 2017.08.30
[API] Thread 5 (스케줄링)  (0) 2017.08.30
[API] Thread 4 (UI 스레드)  (0) 2017.08.30
[API] Thread 3 (Thread 관리)  (0) 2017.08.29
[API] Thread 2 (MultiThread)  (0) 2017.08.29

+ Recent posts