스레드 생성과 종료
Server/Winodw Network 2015. 10. 6. 11:55스레드 생성과 종료
윈도우 API에서 스레드를 사용하려면 CreateThread() 함수를 사용해야 한다.
성공 : 스레드 핸들 리턴, 실패 : NULL
lpThreadAttributes
- SECURITY_ATtRIBUTES 구조체 변수의 주소값을 대입한다.
- 대부분의 경우 NULL을 사용한다.
dwStackSize
- 새로 생성할 스레드에 할당되는 스택 크기
- 0을 사용하면 디폴트로 1MB가 할당된다.
lpStartSize
- 스레드 함수의 시작주소이다.
lpParameter
- 스레드 함수에 전달할 인자
- void형 포인터이므로 32비트 크기의 값 하나만 전달할 수 있다.
- 32비트보다 큰 값을 전달할 때는 구조체 변수에 값을 넣고 이 구조체의 주소값을
전달하면 된다.
- 전달할 인자가 없으면 NULL을 사용한다.
dwCreationFlags
- 스레드 생성을 제어하는 값, 0또는 CREATE_SUSPENDED를 사용한다.
- 0을 사용하면 스레드 생성 후 곧바로 실행된다.
- CREATE_SUSPENDED 사용하면 스레드 생성은 되지만 ResumeThread() 함수를
호출하기 전까지는 실행되지 않는다.
lpThreadId
- DWORD형 변수 주소값으로, 이 변수에 스레드ID가 저장된다.
- 스레드ID 필요하지 않다면 NULL을 사용한다.
윈도우에서 스레드를 종료하는 방법
1. 스레드 함수가 리턴
2. 스레드 함수 내에서 ExitThread() 함수를 호출
3. TerminateThread() 함수를 호출한다.
4. 주 스레드가 종료하면 모든 스레드가 종료된다.
C/C++ 라이브러리 함수를 사용하는 애플리케이션에서는 CreateThread(), ExitThread() 함수보다는 _beginthreadex(), _endthreadex() 함수를 사용하는 것이 좋다.
beginthread(), beginthreadex 원형
_StaratAdress
- 쓰레드를 시작할 함수의 포인터를 받는다.
_StackSize
- 쓰레드에 할당될 스택의 크기
_ArgList
- 첫번째 인자인 쓰레드가 시작할 함수에 인자로 넣어줄 void*이다.
_beginthread 쓰레드의 시작 함수 원형은
void ThreadFunc( void *arglist ); 이다.
benginthread의 경우에는 스레드가 생성된 후에 곧바로 스레드가 시작된다.
_Security
- 보안과 관련된 것, NULL 사용한다.
_InitFlag
- 0또는 CREATE_SUSPENDED 를 받는다.
- 0이라면 쓰레드가 생성될 때, 쓰레드를 곧바로 시작한다.
- CREATE_SUSPENDED라면 나중에 스레드를 시작하고 싶을 때에 ResumeThread()를 이용해서
시작할 수 있다.
_ThrAddr
- 생성된 스레드의 ID를 반환한다.
beginthreadex 스레드의 시작 함수 원형
unsigned int _ _ stdcall ThreadFunc( void *arglist );
** 주의점
_ _stdcall 은 _ _cdecl과 같은 호출규약이다.
beginthreadex() 에서는 _ _ stdcall이라는 함수 호출 규약에 따라서 스레드 시작 함수를 인자로 받는다. _ _cdecl은 c, c++ 기본 함수 호출 규약이라서 따로 명시하지 않아도 되지만
_ _stdcall 은 명시해줘야만 한다.
CreateThread()와 _beginthreadex() 의 차이점
- CreateThread() 함수로 만들어진 스레드에서 C 라이브러리 함수를 사용하면
스레드가 종료될 때 메모리 누수가 일어나서 beginthreadex()를 쓰는 것이 좋다.
WaitForSingleObject()와 WaitForMultipleObjects()
특정 스레드가 종료할 때까지 대기할 수 있다.
hHandle
- 종료를 기다릴 스레드를 가리킬 핸들이다.
dwMilliseconds
- 대기 시간으로 밀리초 단위를 사용한다.
- 이 시간내에 종료하지 않더라도 WaitForSingleObject() 함수는 리턴한다.
이때 리턴값은 WAIT_TIMEOUT이 된다.
- 스레드가 종료한 경우에는 WAIT_OBJECT_0이 리턴된다.
- 대기시간으로 INFINITE 사용하면 스레드 종료할 때까지 무한대기한다.
성공 시 : WAIT_OBJECT_0 ~ WAIT_OBJECT_0 + nCount-1 또는 WIAT_TIMEOUT
실패 시 : WAIT_FAILED
여러개의 스레드가 종료되기를 기다리려면 WaitForMultipleObjects() 함수를 사용해서
한번의 호출로 끝낼 수 있다.
nCount
- 이 함수를 사용하려면 스레드 핸들을 모두 배열에 저장해야한다.
- nCount는 배열 원소 개수이다.
- 최대값은 MAXIMUM_WAIT_OBJECTS(=64) 이다.
lpHandles
- 배열의 시작 주소를 나타낸다.
bWaitAll
- TRUE이면 모든 스레드가 종료할 때까지 대기한다.
- FALSE이면 한 스레드가 종료하는 즉시 리턴한다.
dwMilliseconds
- WaitForSingleObject() 의 인자와 동일
** 주의점
WaitForSingleObject()와 WaitForMultipleObjects() 두 함수는 스레드 종료 대기를 위한 전용 함수가 아니다.
이 두 함수는 스레드의 동기화 목적으로 자주 쓰이는 함수이다.
실행 중지, 재실행
SuspendThread() 함수는 스레드 실행을 일시 중지하고,
ResumeThread() 함수는 스레드를 재실행한다.
운영체제는 스레드의 중지 횟수(suspend count)를 유지하면서 SuspendThread() 함수를 호출할때마다 +1 증가하고 ResumeThread()를 호출할 때마다 -1식 감소한다.
중지 횟수가 0보다 크면 스레드의 실행이 중지된다.
DWORD SuspendThread( HANDLE hThread );
성공시 : 중지 횟수 , 실패 시 : -1
DWORD ResumeThread( HANDLE hThread );
성공시 : 중지 횟수 , 실패 시 : -1
스레드가 대기한다는 것은 CPU시간을 사용하지 않고 기다린다는 뜻이다.
루프를 돌면서 기다리는 방법보다 더 효율적이다.
'Server > Winodw Network' 카테고리의 다른 글
스레드의 우선순위 컨트롤 (0) | 2015.10.12 |
---|---|
프로세스, 스레드의 우선순위 (0) | 2015.10.08 |
프로세스와 스레드 (0) | 2015.10.05 |
로그 기록 (0) | 2015.09.23 |
select 모델 (0) | 2015.08.11 |