* 해당 글은 윤성우의 뇌를 자극하는 윈도우즈 시스템 프로그래밍 도서를 읽고 정리한 글입니다
https://product.kyobobook.co.kr/detail/S000001223395
뇌를 자극하는 윈도우즈 시스템 프로그래밍 | 윤성우 - 교보문고
뇌를 자극하는 윈도우즈 시스템 프로그래밍 |
product.kyobobook.co.kr
* CreateThread 함수
쓰레드 생성
HANDLE CreateThread(
[in, optional] LPSECURITY_ATTRIBUTES lpThreadAttributes,
[in] SIZE_T dwStackSize,
[in] LPTHREAD_START_ROUTINE lpStartAddress,
[in, optional] __drv_aliasesMem LPVOID lpParameter,
[in] DWORD dwCreationFlags,
[out, optional] LPDWORD lpThreadId
);
lpThreadAttributes
: 반환된 핸들을 자식 프로세스에게 상속할 수 있는지의 여부를 결정하는 보안 속성 지정
dwStackSize
: 스택의 초기 사이즈(바이트)
lpStartAddress
: 쓰레드 함수
lpParameter
: 쓰레드 함수 전달인자
dwCreationFlags
: 쓰레드 생성을 제어하는 플래그
lpThreadId
: 쓰레드 Id 반환
CreateThread 함수(processthreadsapi.h) - Win32 apps
호출 프로세스의 가상 주소 공간 내에서 실행할 스레드를 만듭니다.
learn.microsoft.com
* 쓰레드의 흐름을 예측은 불가능하다
ㄴ 초보 프로그래머가 범하는 과오 중 하나임 - 쓰레드의 흐름을 예측하려고 하는 것
* 프로세스가 만들 수 있는 쓰레드의 수는 가상 메모리에 의해 제한된다
기본적으로 모든 쓰레드에는 1MB의 스택 공간을 가지고 있어
/3GB boot.ini 옵션 없이는 32비트 시스템에서는 2,048개 이상의 쓰레드를 만들 수 없다
만약에 기본 스택 크기를 줄인다면, 더 많은 스레드를 만들 수 있다
* 쓰레드의 소멸
1. return 이용
2. ExitThread 함수 호출
void ExitThread(
[in] DWORD dwExitCode
);
dwExitCode
: 쓰레드의 종료 코드
ExitThread 함수(processthreadsapi.h) - Win32 apps
호출 스레드를 종료합니다.
learn.microsoft.com
3. TerminateThread 함수 호출
BOOL TerminateThread(
[in, out] HANDLE hThread,
[in] DWORD dwExitCode
);
hThread
: 종료할 쓰레드에 대한 핸들
dwExitCode
: 쓰레드의 종료 코드
TerminateThread 함수(processthreadsapi.h) - Win32 apps
스레드를 종료합니다.
learn.microsoft.com
* 쓰레드는 메모리를 공유(힙 영역, 데이터 영역, 코드 영역)한다
따라서, 동시 접근에 있어서 문제점이 발생할 수 있다
쓰레드가 동시에 실행되는 것처럼 보이지만 빨라서 그렇게 보이는 것일 뿐 사실은 돌아가면서 실행된다
ㄴ 따라서,
(1) 실행중인 스레드의 변경에 의해서 컨텍스트 스위칭은 빈번하게 발생한다
(2) 둘 이상의 쓰레드가 같은 메모리 영역을 동시에 참조하는 것은 문제를 일으킬 가능성이 매우 높다
* 프로세스로부터의 쓰레드 분리한다
프로세스가 소유하는 쓰레드의 핸들을 반환함으로써 쓰레드의 Usage Count를 1로 두겠다는 뜻
이는 쓰레드가 종료되는 시점에 쓰레드의 리소스를 반환하기 위함
* strtok 함수 문제점
- 내부적으로 전역 static 변수를 사용하여 상태를 저장
- 멀티 쓰레드 환경에서 여러 쓰레드가 동일한 문자열을 strtok로 처리하면,
한 쓰레드에서 상태가 변경될 수 있어 예기치 않은 동작일 발생할 수 있다
* strtok 함수 문제점을 개선한 strtok_s 함수
- 내부 상태를 함수 외부에서 직접 관리할 수 있도록 context 포인터를 추가로 받는다
- 각 쓰레드가 별도의 context를 유지하면,
동일한 문자열을 여러 쓰레드에서 동시에 처리해도 충돌이 발생하지 않는다
char* strtok_s(
char* str,
const char* delimiters,
char** context
);
str
: 찾을 토큰 또는 토큰이 포함된 문자열
delimiters
: 사용할 구분 기호 문자 집합
context
: 함수 호출 간에 위치 정보를 저장하는데 사용
strtok_s, _strtok_s_l, wcstok_s, _wcstok_s_l, _mbstok_s, _mbstok_s_l
자세한 정보: strtok_s, _strtok_s_l, wcstok_s, _wcstok_s_l, _mbstok_s, _mbstok_s_l
learn.microsoft.com
* _beginthread 함수
쓰레드 생성
쓰레드를 위해 독립적인 메모리 블록을 할당
uintptr_t _beginthreadex(
void *security,
unsigned stack_size,
unsigned ( __stdcall *start_address )( void * ),
void *arglist,
unsigned initflag,
unsigned *thrdaddr
);
_beginthread, _beginthreadex
자세한 정보: _beginthread, _beginthreadex
learn.microsoft.com
* _beginthreadex 함수는 쓰레드 소멸시 ExitThread 함수 말고 _endThreadex를 써야 한다
* SuspendThread 함수
: 지정된 쓰레드를 일시 중단
DWORD SuspendThread(
[in] HANDLE hThread
);
hThread
: 일시 중단될 쓰레드에 대한 핸들
SuspendThread 함수(processthreadsapi.h) - Win32 apps
지정된 스레드를 일시 중단합니다.
learn.microsoft.com
* ResumeThread 함수
: 쓰레드의 일시 중단 횟수를 감소
일시 중단 횟수가 0으로 감소하면 쓰레드의 실행이 다시 시작된다
ResumeThread 함수(processthreadsapi.h) - Win32 apps
스레드의 일시 중단 횟수를 감소합니다. 일시 중단 횟수가 0으로 감소하면 스레드 실행이 다시 시작됩니다.
learn.microsoft.com
* 프로세스는 실행의 주체가 아닌 쓰레드를 담는 그릇
ㄴ 따라서, 프로세스 안에서 동작하는 쓰레드가 우선순위를 갖는다
'IT공부 > IT서적' 카테고리의 다른 글
[뇌를 자극하는 윈도우즈 시스템 프로그래밍] 15장. 쓰레드 풀링(Pooling), 16장. 컴퓨터 구조 - 4 (0) | 2025.02.20 |
---|---|
[뇌를 자극하는 윈도우즈 시스템 프로그래밍] 13장, 14장. 쓰레드 동기화 기법 1, 쓰레드 동기화 기법 2 (0) | 2025.02.17 |
[윤성우 열혈 C프로그래밍] 릴리즈 빌드(최적화 컴파일러 OFF), 어셈블리 코드 - Chapter25 (0) | 2025.02.12 |
[윤성우 열혈 C프로그래밍] 릴리즈 빌드(최적화 컴파일러 OFF), 어셈블리 코드 - Chapter24, Chapter26, Chapter27 (0) | 2025.02.11 |
[윤성우 열혈 C프로그래밍] 매크로 # 연산자(P572 ~ P575) (0) | 2025.02.11 |