본문 바로가기

공부/tcp/ip 프로그래밍

19장 windows에서의 쓰레드 사용

반응형

19장.pptx

윈도우는 가장 기본이 되는 프로그램의 main함수가 반환되면 그 안에 담겨있는 모든 쓰레드들도 종료

리눅스는 가장 기본이 되는 프로그램의 main함수가 반환되어도 그 안에 담겨있는 모든 쓰레드들은 남아있음(리눅스는 쓰레드를 삭제해주는 함수를 꼭 사용해야 함)

 

핸들, 커널오브젝트, 리소스의 관계

 

커널오브젝트를 만드는 이유 : 리소스를 효과적으로 관리하기 위해서

 

리소스를 쓰레드라고 가정
1. 프로그램에서 쓰레드를 만들어 달라고 요청
2. OS는 쓰레드(리소스)를 생성하고 그에 관한 명세서로 커널오브젝트를 만듬
3. OS는 프로그램에게 커널오브젝트를 가리키는 handle을 전달

 

1. 프로그램이 핸들에 어떠한 행위를 요청
2. OS는 리소스에 요청을 반영
3. OS는 커널오브젝트에 리소스의 변화를 반영

 

CreateThread 함수는 Win32 API 에서 제공되는 함수고
_beginthread, _beginthreadex 함수는 C / C++ Runtime-Library 에서 제공되는 함수

맨 처음 만들어진 라이브러리는 단일 쓰레드 구조를 위해 만들어짐
CreateThread 함수를 통해 쓰레드 생성
이 쓰레드를 멀티 쓰레드로 C/C++ 표준함수를 이용하면 안정적으로 동작 안함

이를 해결하기 위해서 라이브러리와 쓰레드를 생성하는 함수를 고쳐
다중 쓰레드 라이브러리와 _beginthread, _beginthreadex함수를 만듦
_beginthread, _beginthreadex로 만들어진 쓰레드는 멀티 쓰레드 구조를 위한 쓰레드
이 쓰레드를 멀티 쓰레드로 C/C++ 표준함수를 이용하면 안정적으로 동작

 

단일 쓰레드 모델을 위한 쓰레드 생성 함수

#include <windows.h>

 

HANDLE CreateThread(

LPSECURITY_ATTRIBUTES lpThreadAttributes,

SIZE_T dwStackSize,

LPTHREAD_START_ROUTINE lpStartAddress,

LPVOID lpParameter,

DWORD dwCreationFlags,

SPDWORD lpThreadId

};

성공시 쓰레드 핸들, 실패시 NULL 반환

 

lpThreadAttributes : 쓰레드의 보안관련 정보전달, 디폴트 보안설정을 위해서 NULL전달

dwStackSize : 쓰레드에게 할당할 스택의 크기를 전달, 0전달하면 디폴트 크기의 스택 생성

lpStartAddress : 쓰레드의 main 함수정보 전달

lpParameter : 쓰레드의 main 함수호출 시 전달할 인자정보 전달

dwCreationFlags : 쓰레드 생성 이후의 행동을 결정, 0을 전달하면 생성과 동시에 실행가능한 상태가 됨

lpThreadId : 쓰레드 ID의 저장을 위한 변수의 주소 값 전달

 

다중 쓰레드 모델을 위한 쓰레드에 안전한 C 표준함수의 호출을 위한 쓰레드 생성

#include <process.h>

 

uintptr_t _beginthreadex(

void* security,

unsigned stack_size,

unsigned (*start_address) (void*),

void* arglist,

unsigned initflag,

unsigned* thrdaddr

);

성공시 쓰레드 핸들, 실패시 0 반환

 

위의 함수 인자와 같음

 

쓰레드 ID와 핸들

예) hThread =

(HANDLE)_beginthreadex(NULL, 0, ThreadFunc, (void*)*param, 0, &threadID);

핸들(hThread)의 정수 값은 프로세스가 달라지면 중복될 수 있다
쓰레드의 ID(&threadID)는 프로세스 영역을 넘어서 중복되지 않음
쓰레드의 ID(&threadID)는 운영체제가 생성하는 모든 쓰레드 각각을 구분하는 용도

 

커널 오브젝트의 두 가지 상태


Signaled 상태 : 해당 리소스가 특정 상황에 도달한 상태
Non signaled 상태 : 해당 리소스가 특정 상황에 이르지 않은 상태

리소스가 어떠한 원하는 상태가 되었을 때 운영체제는

리소스에 해당하는 커널오브젝트의 변수에 시그널을 표시

리소스에 따라서 원하는 상태는 다름

(쓰레드는 종료가 언제 될 것인가가 가장 큰 관심이므로 종료가 원하는 상태임)

 

*함수호출이후 signaled 상태에서 다시 non-signaled상태가 되는 되돌리는 커널 오브젝트를 auto-reset 모드 커널 오브젝트라고하고 자동으로 non-signaled상태가 되지 않는 커널 오브젝트를 manual-reset모드 커널 오브젝트라고 함

 

하나의 커널 오브젝트에 대해서 signaled 상태인지를 확인하기 위해서 호출하는 함수

#include <windows.h>

 

DWORD WaitForSingleObject(HANDLE hHandle, DWORD dwMilliseconds);

signaled 상태로 인한 반환 시, WAIT_OBJECT_0 반환, 타임아웃으로 인한 반환 시 WAIT_TIMEOUT 반환

 

hHandle : 상태확인의 대상이 되는 커널 오브젝트의 핸들을 전달

dwMilliseconds : 1/1000초 단위로 타임아웃을 지정, 인자로 INFINITE 전달 시, 커널 오브젝트가 signaled 상태가 되기 전에는 반환하지 않는다

 

이번트 발생에 의해서(signaled 상태가 되어서)반환되면, 해당 커널 오브젝트를 다시 non-signaled상태

로 되돌림

 

 

둘 이상의 커널 오브젝트를 대상으로 상태를 확인하는 경우에 호출하는 함수

#include <windows.h>

 

DWORD WaitForMultipleObjects(

DWORD nCount, const HANDLE* lpHandles, BOOL bWaitAll, DWORD dwMilliseconds);

signaled 상태로 인한 반환 시, WAIT_OBJECT_0 반환, 타임아웃으로 인한 반환 시 WAIT_TIMEOUT 반환

 

nCount : 검사할 커널 오브젝트의 수 전달

lpHandles : 핸들정보를 담고 있는 배열의 주소 값 전달

bWaitAll : TRUE 전달 시, 모든 검사대상이 signaled 상태가 되어야 반환, FALSE 전달시, 검사대상 중

              하나라도 signaled 상태가 되면 반환

dwMillliseconds : 1/1000초 단위로 타임아웃 지정, 인자로 INFINITE 전달 시, 커널 오브젝트가 signaled상태가 되기 전에는 반환하지 않는다

 

이번트 발생에 의해서(signaled 상태가 되어서)반환되면, 해당 커널 오브젝트를 다시 non-signaled상태

로 되돌림

반응형