카테고리 없음

스레드와 C런타임 라이브러리

Ginger-Prince 2015. 10. 8. 21:47

스레드를 만들때 Win32 API 함수인 CreateThread()를 사용하였다.

하지만 CreateThread()함수를 쓸 때에는 조심하여야한다.

 

대부분의 프로그램은 C런타임 라이브러리에 상당한 의존을 한다.

C런타임 라이브러리는 각각의 스레드가 라이브러리를 사용할 때 적절하게 초기화되어야 하는

특징을 가지고 있는 데  그 이유는

 

1. Win32 API는 운영체제에 의해 구현되었다.

   하지만  C런타임 라이브러리는 컴파일러 제작사에 의해서 구현되었기 때문에

   서로 불일치하게 되면 스레드가 생성될 때 C런타임 라이브러리를 코드의 밖으로 빠지게 한다.

 

2. C런타임 라이브러리의 어떤 함수들은 함수 사이에서 상태를 유지하고 있다.

 

 

이런 경우를 대비해서 런타임 라이브러리는 각 스레드에 대해서 C런타임 라이브러리를 초기화하는 함수인 _beginthread와 _beginthreadex를 제공한다.

 

ExitThread를 사용하면 endthread를 호출할 필요가 없다.

올바른 정리 프로시저는 스레드 시작 프로시저가 리턴될 때 런타임 라이브러리에 의해서 자동으로 호출되기 때문에

 

C런타임 라이브러리는 CreateThread 호출에 의해서 스레드를 사용하는 경우를 검출할 수 있다.

_beginthread의 호출에 의해서 이루어지는 대부분의 초기화 작업을 동적으로 수행할 수 있다.

그러나 시그널이나 예외 처리, 메모리 leak과 같은 경우에 대처할 수 없다.

 

_beginthread함수의 원형

 

unsinged long _beginthread( void (__cdecl *start _adress) (void *), unsigned stack_size, void *arglist);

 

start _adress

- 새 스레드가 수행을 시작하면 호출할 사용자 함수의 주소

 

stack_size

- 새 스레드의 스택 크기(바이트). 이 매개변수가 0이면 스택 크기는 현재 프로세스의 주 스레드와 같게된다.

- 시스템은 스택의 상한값을 1MB로 제한하여서 함수가 제한없이 재귀적으로 호출하는 것을 방지하며, 4기가바이트의 주소 공간이 모두 사용되는 것을 막는다.

 

arlist

- start_adress가 가리키는 스레드 시작 프로시저에 전달되는 임의의 인자

 

_beginthreadex의 원형

 

unsinged long _beginthreadex ( void * security, unsinged stack_size,

unsinged (stdcall *start_proc) (void *), void *arg, unsinged initflag, unsigned * thraddr);

 

 

security

- 새로 생성된 스레드의 보안과 속성을 지정하는 SECURITY_ATTRIBUTE의 구조체 포인터

-  NULL이면 스레드는 디폴트 보안 속성으로 생성된다.

- 현재 프로세스의 자식 프로세스는 스레드 핸들을 상속받을 수 없다.

 

stack_size

- 새로운 스레드에 할당할 스택 크기(바이트) 이 값이 0이면 스택 크기는 현재 프로세스의

   주 스레드의 스택 크기와 같다.

- 시스템은 크기의 상한을 1MB로 정해서 함수가 제한없이 재귀적으로 동작하는 것을 방지한다.

 

start_proc

- 새로운 스레드가 수행을 시작할 때 호출할 사용자 함수의 주소.

 

arg

- 사용자 정의 32비트 값

- Start_proc이 지정한 루틴으로서 새로 생성된 스레드의 lpThreadParameter로 값이 넘겨진다.

 

initflag

- 스레드 생성을 조절하는 추가적인 매개변수

- 이 값이 CREATE_SUSPENDED값이면 스레드는 대기 카운트 1의 값을 갖고 대기상태로 생성

  된다. ResumeThread 함수의 호출에 의해서 수행을 시작하게 된다.

  이 값이 0이면 스레드는 즉시 수행을 시작하게 된다.

 

thraddr

- 스레드 식별자를 받을 DWORD 값의 포인터이다.

 

 

** C런타임 라이브러리를 사용하는 프로그램에서 ExitThread 함수를 사용하면 안된다.

ExitThread 함수를 호출하는 경우에 스레드가 런타임 환경을 지원하기 위해서 할당된

자원을 정리할 기회를 얻을 수 없다.

 

스레드가 시작 함수에서 리턴하지 않고, 종료하는 경우엔 ExitThread 호출하는 대신

_endthreadex 호출해야 한다.