Download presentation
Presentation is loading. Please wait.
1
MultiThread
2
Process와 Thread (1/3) 용어 Process Thread Primary thread Context switch
메모리를 비롯한 각종 리소스를 담고 있는 컨테이너(container)로서 정적인 개념 Thread 실제 CPU 시간을 할당받아 수행되는 실행 단위로서 동적인 개념 Primary thread main() 또는 WinMain() 함수에서 시작되는 thread로, Process가 시작할 때 생성 Context switch CPU와 운영체제의 협동으로 이루어지는 thread 실행 상태의 저장과 복원 작업 Multithread
3
Process와 Thread (2/3) Context switching CPU ① ② thread① 레지스터 thread②
Multithread
4
Process와 Thread(3/3) Multithread
5
Thread 생성과 종료 (1/6) thread 생성에 필요한 요소 thread function의 시작 주소
Multithread
6
Thread 생성과 종료 (2/6) Process의 주소 공간 두 개의 함수 세 개의 thread f() { ... }
main() 주 thread의 실행 스택 thread ①의 코드 thread ②의 주 thread thread ①, ② Process의 주소 공간 두 개의 함수 세 개의 thread Multithread
7
Thread 생성과 종료 (3/6) CreateThread() 함수
thread를 생성한 후 thread 핸들(thread handle)을 리턴 HANDLE CreateThread ( LPSECURITY_ATTRIBUTES lpThreadAttributes, // NULL SIZE_T dwStackSize, // 0 LPTHREAD_START_ROUTINE lpStartAddress, // thread 함수 LPVOID lpParameter, // thread 함수 인자 DWORD dwCreationFlags, // 0 또는 CREATE_SUSPENDED LPDWORD lpThreadId // thread ID ) ; 성공: thread 핸들, 실패: NULL Multithread
8
Thread 생성과 종료 (4/6) thread 함수 정의
DWORD WINAPI ThreadProc (LPVOID lpParameter) { ... } DWORD WINAPI f(LPVOID arg) { … return 0; } int main() { HANDLE hThread1 = CreateThread(NULL, 0, f, NULL, 0, NULL); if (hThread1 == NULL) error_handling; Multithread
9
Thread 생성과 종료 (5/6) thread 종료 방법 ① thread 함수가 리턴
② thread 함수 내에서 ExitThread() 함수를 호출 ③ TerminateThread() 함수를 호출 ④ 주 thread가 종료하면 모든 thread가 종료 Multithread
10
Thread 생성과 종료 (6/6) thread 종료 함수 void ExitThread (
DWORD dwExitCode // 종료 코드 ) ; BOOL TerminateThread ( HANDLE hThread, // 종료할 thread를 가리키는 핸들 DWORD dwExitCode // 종료 코드 ) ; 성공: 0이 아닌 값, 실패: 0 See example of ExThread1.cpp Multithread
11
Thread 조작 – 우선 순위 (1/5) 용어 thread scheduling priority class
윈도우가 각 thread에게 CPU 시간을 적절히 분배하기 위한 정책 priority class Process 속성으로, 한 Process가 생성한 thread는 모두 동일한 우선순위 클래스를 가짐 priority level thread 속성으로, 한 Process에 속한 thread 사이에서 상대적인 우선순위를 결정할 때 사용 base priority 우선순위 클래스와 우선순위 레벨을 결합한 값으로, thread 스케줄링에 사용 Multithread
12
Thread 조작 – 우선 순위 (2/5) 우선 순위 클래스(for process scheduling)
REALTIME_PRIORITY_CLASS(실시간) HIGH_PRIORITY_CLASS(높음) ABOVE_NORMAL_PRIORITY_CLASS(보통 초과; 윈도우2000/XP/2003) NORMAL_PRIORITY_CLASS(보통) BELOW_NORMAL_PRIORITY_CLASS(보통 미만; 윈도우2000/XP/2003) IDLE_PRIORITY_CLASS(낮음) Multithread
13
Thread 조작 – 우선 순위 (3/5) 우선 순위 레벨(for thread scheduling)
THREAD_PRIORITY_TIME_CRITICAL THREAD_PRIORITY_HIGHEST THREAD_PRIORITY_ABOVE_NORMAL THREAD_PRIORITY_NORMAL THREAD_PRIORITY_BELOW_NORMAL THREAD_PRIORITY_LOWEST THREAD_PRIORITY_IDLE Multithread
14
Thread 조작 – 우선 순위 (4/5) 우선 순위 기반 thread 스케줄링 (낮음) 기초 우선순위 (높음) ...
스케줄러 CPU thread (낮음) 기초 우선순위 (높음) 세 개의 thread를 교대로 수행 Multithread
15
Thread 조작 – 우선 순위 (5/5) 우선 순위 레벨 조작 함수 See example of ExThread2.cpp
BOOL SetThreadPriority ( HANDLE hThread, // thread 핸들 int nPriority // 우선순위 레벨값 ) ; 성공: 0이 아닌 값, 실패: 0 int GetThreadPriority ( HANDLE hThread // thread 핸들 ) ; 성공: 우선순위 레벨값, 실패: THREAD_PRIORITY_ERROR_RETURN See example of ExThread2.cpp Multithread
16
Thread 조작 – thread 종료 대기 (1/4)
WaitForSingleObject() 함수 특정 thread가 종료할 때까지 대기 WaitForSingleObject() 함수 사용 예 DWORD WaitForSingleObject ( HANDLE hHandle, DWORD dwMilliseconds ) ; 성공: WAIT_OBJECT_0 또는 WAIT_TIMEOUT, 실패: WAIT_FAILED HANDLE hThread = CreateThread(...); WaitForSingleObject(hThread, INFINITE); Multithread
17
Thread 조작 – thread 종료 대기 (2/4)
WaitForMultipleObjects() 함수 두 개 이상의 thread가 종료할 때까지 대기 DWORD WaitForMultipleObjects ( DWORD nCount, const HANDLE* lpHandles, BOOL bWaitAll, DWORD dwMilliseconds ) ; 성공: WAIT_OBJECT_0 ~ WAIT_OBJECT_0 + nCount-1 또는 WAIT_TIMEOUT, 실패: WAIT_FAILED Multithread
18
Thread 조작 – thread 종료 대기 (3/4)
WaitForMultipleObjects() 함수 사용 예 ① // 모든 thread 종료를 기다릴 경우 HANDLE hThread[2]; HANDLE hThread[0] = CreateThread(...); HANDLE hThread[1] = CreateThread(...); WaitForMultipleObjects(2, hThread, TRUE, INFINITE); Multithread
19
Thread 조작 – thread 종료 대기 (4/4)
WaitForMultipleObjects() 함수 사용 예 ② // 두 thread 중 하나의 종료를 기다릴 경우 HANDLE hThread[2]; HANDLE hThread[0] = CreateThread(...); HANDLE hThread[1] = CreateThread(...); DWORD retval = WaitForMultipleObjects(2, hThread, FALSE, INFINITE); switch(retval){ case WAIT_OBJECT_0: // hThread[0] 종료 break; case WAIT_OBJECT_0+1: // hThread[1] 종료 case WAIT_FAILED: // 오류 발생 } Multithread
20
Thread 조작 – 실행 중지와 재실행 (1/2)
실행 중지 함수 ① 재실행 함수 DWORD SuspendThread ( HANDLE hThread // thread 핸들 ) ; 성공: 중지 횟수, 실패: -1 DWORD ResumeThread ( HANDLE hThread // thread 핸들 ) ; 성공: 중지 횟수, 실패: -1 Multithread
21
Thread 조작 – 실행 중지와 재실행 (2/2)
실행 중지 함수 ② thread가 실행을 멈추고 일정 시간동안 대기 void Sleep ( DWORD dwMilliseconds // 밀리초(ms) ) ; See example of ExThread3.cpp Multithread
22
멀티Thread TCP 서버 (1/3) 기본 구조 DWORD WINAPI ProcessClient(LPVOID arg) {
// 전달된 소켓 ③ SOCKET client_sock = (SOCKET)arg; // 클라이언트 정보 얻기 ④ addrlen = sizeof(clientaddr); getpeername(client_sock, (SOCKADDR *)&clientaddr, &addrlen); // 클라이언트와 데이터 통신 ⑤ while(1){ ... } closesocket(client_sock); return 0; Multithread
23
멀티Thread TCP 서버 (2/3) 기본 구조 (cont’d) int main(int argc, char* argv[])
{ ... while(1){ // 클라이언트 접속 수용 ① client_sock = accept(listen_sock, ...); // thread 생성 ② CreateThread(NULL, 0, ProcessClient, (LPVOID)client_sock, 0, &ThreadId); } Multithread
24
멀티Thread TCP 서버 (3/3) 소켓과 연관된 주소 정보 얻기 int getpeername ( SOCKET s,
struct sockaddr* name, int* namelen ) ; 성공: 0, 실패: SOCKET_ERROR int getsockname ( SOCKET s, struct sockaddr* name, int* namelen ) ; 성공: 0, 실패: SOCKET_ERROR See example of TCPServer2.cpp Multithread
25
Thread 동기화 (1/4) thread synchronization 필요성 멀티thread의 공유 데이터 접근 제어
int money = 1000 ... ① read money into ECX ② ECX = ECX ③ write ECX into money thread 2 ② ECX = ECX 공유 변수 Multithread
26
Thread 동기화 (2/4) 다양한 thread 동기화 기법 종류 주요 용도 임계영역 (critical section)
(한 Process에 속한 thread에만 사용 가능) 뮤텍스 (mutex) (서로 다른 Process에 속한 thread에도 사용 가능) 이벤트 (event) 특정 사건 발생을 다른 thread에게 알림 세마포 (semaphore) 한정된 개수의 자원을 여러 thread가 사용하려고 할 때, 접근을 제한 대기 가능 타이머 (waitable timer) 특정 시간이 되면 대기 중인 thread를 깨움 Multithread
27
Thread 동기화 (3/4) thread 동기화 원리 thread 1 매개체 thread 2 진행 대기 Multithread
28
Thread 동기화 (4/4) thread 동기화 원리 (cont’d) 동기화 객체 비신호 상태 신호 상태
Wait*() 함수로 감지 Multithread
29
임계 영역 (1/3) critical section 특징
두 개 이상의 thread가 공유 리소스를 접근할 때, 오직 하나의 thread 접근만 허용해야 하는 경우에 사용 특징 유저(user) 영역 메모리에 존재하는 구조체이므로 한 Process에 속한 thread 동기화에만 사용 가능 일반적인 동기화 객체보다 빠르고 효율적 Multithread
30
임계 영역 (2/3) 임계 영역 사용 예 #include <windows.h>
CRITICAL_SECTION cs; // ① // thread 1 DWORD WINAPI Thread1(LPVOID arg) { ... EnterCriticalSection(&cs); // ③ // 공유 리소스 접근 LeaveCriticalSection(&cs); // ④ } Multithread
31
임계 영역 (3/3) 임계 영역 사용 예 (cont’d) See example of ExCriticalSection.cpp
// thread 2 DWORD WINAPI Thread2(LPVOID arg) { ... EnterCriticalSection(&cs); // ③ // 공유 리소스 접근 LeaveCriticalSection(&cs); // ④ } int main() InitializeCriticalSection(&cs); // ② // thread 생성과 종료 DeleteCriticalSection(&cs); // ⑤ See example of ExCriticalSection.cpp Multithread
32
이벤트 객체 (1/3) event object 이벤트 객체를 이용한 동기화 예
특정 사건 발생을 다른 thread에게 알릴 때 주로 사용 이벤트 객체를 이용한 동기화 예 ① 이벤트 객체를 비신호 상태로 생성 ② 한 thread가 작업을 진행하고, 나머지 thread는 이벤트 객체에 대해 Wait*() 함수를 호출함으로써 이벤트 객체가 신호 상태가 되기를 기다림 ③ thread가 작업을 완료하면, 이벤트를 신호 상태로 바꿈 ④ 기다리고 있던 모든 thread가 깨어나서 작업을 진행 Multithread
33
이벤트 객체 (2/3) 이벤트 객체 상태 변경 이벤트 객체의 종류 자동 리셋(auto-reset) 이벤트
수동 리셋(manual-reset) 이벤트 BOOL SetEvent (HANDLE hEvent) ; // 비신호 상태 신호 상태 BOOL ResetEvent (HANDLE hEvent) ; // 신호 상태 비신호 상태 Multithread
34
이벤트 객체 (3/3) 이벤트 객체 생성 HANDLE CreateEvent (
LPSECURITY_ATTRIBUTES lpEventAttributes, BOOL bManualReset, BOOL bInitialState, LPCTSTR lpName ) ; 성공: 이벤트 핸들, 실패: NULL See example of ExEvent.cpp Multithread
Similar presentations