쓰레드의 성격과 특성
- 쓰레드는 힙, 데이터, 코드 영역을 공유함
-> 전역변수를 쓰레드가 접근할 수 있음
#include <stdio.h>
#include <Windows.h>
#include <tchar.h>
static int total = 0;
DWORD WINAPI ThreadProc(LPVOID lpParam)
{
DWORD* nptr = (DWORD*)lpParam;
DWORD num1 = *nptr;
DWORD num2 = *(nptr + 1);
for (DWORD i = num1; i <= num2; i++)
{
total += i;
}
return 0;
}
int _tmain(int argc, TCHAR* argv[])
{
DWORD dwThreadId[3];
HANDLE hThread[3];
DWORD param[] = { 1,3,4,7,8,10 };
DWORD result = 0;
hThread[0] = CreateThread(
NULL,
0, // 스택의 크기 1MB로 설정
ThreadProc, // 쓰레드로 사용할 함수
(LPVOID)(¶m[0]), // 쓰레드 함수의 전달 인자
0,
&dwThreadId[0] // 쓰레드 ID 반환
);
hThread[1] = CreateThread(
NULL,
0, // 스택의 크기 1MB로 설정
ThreadProc, // 쓰레드로 사용할 함수
(LPVOID)(¶m[2]), // 쓰레드 함수의 전달 인자
0,
&dwThreadId[1] // 쓰레드 ID 반환
);
hThread[2] = CreateThread(
NULL,
0, // 스택의 크기 1MB로 설정
ThreadProc, // 쓰레드로 사용할 함수
(LPVOID)(¶m[4]), // 쓰레드 함수의 전달 인자
0,
&dwThreadId[2] // 쓰레드 ID 반환
);
if (hThread[0] == NULL || hThread[1] == NULL || hThread[2] == NULL)
{
_tprintf(_T("Thread create error\n"));
return -1;
} // 쓰레드를 생성하지 못하면 NULL이 반환
WaitForMultipleObjects(3, hThread, TRUE, INFINITE); // 쓰레드가 종료될 때까지 대기
GetExitCodeThread(hThread[0], &result);
total += result;
GetExitCodeThread(hThread[1], &result);
total += result;
GetExitCodeThread(hThread[2], &result);
total += result;
_tprintf(_T("total (1~10) : %d\n"), total);
CloseHandle(hThread[0]);
CloseHandle(hThread[1]);
CloseHandle(hThread[2]);
return 0;
}
- 동시접근의 문제점
-> 둘 이상의 쓰레드가 하나의 전역 변수에 접근을 하게 되면 문제가 일어날 수 있음
-> 쓰레드 A가 연산을 하고 있는데 연산 값을 레지스터에 저장하고 다시 전역 변수에 반환해주기 전에 쓰레드 B가 running이 되어 컨텍스트 스위칭이 일어나는 경우 레지스터 정보를 잠시 메모리에 임시 저장 후 레지스터를 비워줌
-> 쓰레드 B가 연산 후 전역 변수에 저장 후 쓰레드 A가 다시 running이 되면 임시 저장한 데이터를 레지스터로 다시 가져온 다음 전역 변수에 데이터를 저장함
-> 이러한 문제를 방지하기 위해서는 쓰레드가 작업하는 동안에는 같은 메모리 영역을 접근하면 안됨
- 프로세스로부터 쓰레드 분리
-> 쓰레드는 생성부터 UC가 2
-> 쓰레드 종료시 -1이 되고 closeHandle() 호출 시 -1이 되어 0이 됨
-> 쓰레드를 생성과 동시에 closeHandle()을 해주게 되면 쓰레드 종료시 UC가 0이 되게 됨 : 쓰레드 분리
* 이럴 경우 쓰레드를 생성한 프로세스에서 쓰레드의 종료 코드를 얻을 수 없음
ANSI 표준 C라이브러리와 쓰레드
- ANSI 표준 C라이브러리는 쓰레드 기반에 안정적이지 않음
-> 동시접근 문제
- CreateThread -> _beginthreadex
-> _beginthreadex는 내부적으로 createThread 함수를 호출해주고 쓰레드별로 별도의 메모리 공간을 할당
- ExitThread -> _endthreadex
-> _endthreadex는 할당한 메모리 공간을 해제함
'Programming > System Programming' 카테고리의 다른 글
윈도우즈 시스템 프로그래밍 - 13. 쓰레드 동기화 기법1(1) (0) | 2020.08.03 |
---|---|
윈도우즈 시스템 프로그래밍 - 12. 쓰레드의 생성과 소멸(3) (0) | 2020.07.26 |
윈도우즈 시스템 프로그래밍 - 12. 쓰레드의 생성과 소멸(1) (0) | 2020.07.26 |
윈도우즈 시스템 프로그래밍 - 11. 쓰레드의 이해(5) (0) | 2020.07.23 |
윈도우즈 시스템 프로그래밍 - 11. 쓰레드의 이해(4) (0) | 2020.07.23 |