멀티스레드 Chapter 05. * 학습목표 멀티스레드의 필요성을 이해하고 기본 개념을 익힘.

Slides:



Advertisements
Similar presentations
contents Thread function Create Thread Terminate Thread
Advertisements

ㅎㅎ 구조체 구조체 사용하기 함수 매개변수로서의 구조체 구조체 포인터와 레퍼런스 구조체 배열.
ㅎㅎ 구조체 C++ 프로그래밍 기초 : 객체지향의 시작 구조체 사용하기 함수 매개변수로서의 구조체 구조체 포인터와 레퍼런스
6장. 멀티스레드 멀티스레드 프로그래밍의 필요성을 이해하고 기본 개념을 익힌다.
제14장 동적 메모리.
인공지능실험실 석사 2학기 이희재 TCP/IP Socket Programming… 제 11장 프로세스간 통신 인공지능실험실 석사 2학기 이희재
최윤정 Java 프로그래밍 클래스 상속 최윤정
9장. C 언어의 핵심! 함수. 9장. C 언어의 핵심! 함수 9-1 함수의 정의와 선언 main 함수 다시 보기 : 함수의 기본 형태 { } 그림 9-1.
Network Lab. Young-Chul Hwang
Java로 배우는 디자인패턴 입문 Chapter 5. Singleton 단 하나의 인스턴스
제 9 장 구조체와 공용체.
Chapter 4 Multi-Threaded Socket
컴퓨터 프로그래밍 기초 [Final] 기말고사
Visual C++ Programming Tree Control/MultiThread
스레드의 개념과 동작 원리를 이해한다. MFC 스레드의 두 종류인 작업자 스레드와 UI 스레드 사용법을 익힌다.
Visual C++ Programming Tree Control/MultiThread
MultiThread.
3장. 변수와 연산자. 3장. 변수와 연산자 3-1 연산자, 덧셈 연산자 연산자란 무엇인가? 연산을 요구할 때 사용되는 기호 ex : +, -, *, / 3-1 연산자, 덧셈 연산자 연산자란 무엇인가? 연산을 요구할 때 사용되는 기호 ex : +, -, *, /
쉽게 풀어쓴 C언어 Express 제17장 동적메모리와 연결리스트 C Express Slide 1 (of 13)
4장. 웹로직 서버상에서의 JDBC와 JTA의 운용
5장. 참조 타입.
Multi-thread Programming
07. 디바이스 드라이버의 초기화와 종료 김진홍
Visual C++ Programming MultiThread
스레드란? 멀티 태스킹(muli-tasking)는 여러 개의 애플리케이션을 동시에 실행하여서 컴퓨터 시스템의 성능을 높이기 위한 기법 그림23-1. 병철 처리의 예.
Chap08 다중 스레드 8.1 스레드 개요 8.2 Thread 클래스와 스레드 생명주기 8.3 스레드 생성과 사용
11장. 포인터 01_ 포인터의 기본 02_ 포인터와 Const.
SqlParameter 클래스 선문 비트 18기 발표자 : 박성한.
Chapter 06. UDP 서버/클라이언트.
인공지능실험실 박사 1학기 장성만 TCP/IP Socket Programming… 9장 소켓의 다양한 옵션 인공지능실험실 박사 1학기 장성만
TCP/IP 응용 프로그램에 적용 가능한 다양한 소켓 옵션을 이해하고 활용한다.
23장. 구조체와 사용자 정의 자료형 2.
Sungkyunkwan University OS Project Dongkun Shin
TCP/IP Socket Programming…
10장. 예외처리.
13. 연산자 오버로딩.
Method & library.
사용자 함수 사용하기 함수 함수 정의 프로그램에서 특정한 기능을 수행하도록 만든 하나의 단위 작업
메모리 관리 & 동적 할당.
TCP/IP 응용 프로그램에 적용 가능한 다양한 소켓 옵션을 이해하고 활용한다.
24장. 파일 입출력.
19. 함수 포인터와 void 포인터.
Chapter6 : JVM과 메모리 6.1 JVM의 구조와 메모리 모델 6.2 프로그램 실행과 메모리 6.3 객체생성과 메모리
자바 5.0 프로그래밍.
데이터베이스실험실 석사 2학기 조정희 TCP/IP Socket Programming… 제 19장 윈도우 기반의 쓰레드 동기화 데이터베이스실험실 석사 2학기 조정희
컴퓨터 프로그래밍 기초 - 10th : 포인터 및 구조체 -
데이터베이스실험실 석사 2학기 조정희 TCP/IP Socket Programming… 제 18장 윈도우 기반 쓰레드 사용하기 데이터베이스실험실 석사 2학기 조정희
Part 4 클래스 라이브러리 Chapter 10 : 다중 스레드 Chapter 11 : 패키지와 주요 클래스
IOCP 2005/11/10.
Lab 8 Guide: 멀티스레딩 예제 2 * Critical Section을 이용한 멀티스레딩 동기화 (교재 15장, 쪽)
컴퓨터 프로그래밍 기초 - 8th : 함수와 변수 / 배열 -
Fucntion 요약.
( Windows Service Application Debugging )
Chapter 04. TCP 서버/클라이언트.
클래스 : 기능 CHAPTER 7 Section 1 생성자(Constructor)
제 8장. 클래스의 활용 학기 프로그래밍언어및실습 (C++).
Chapter 02. 윈도우 소켓 시작하기.
3. 모듈 (5장. 모듈).
구조체(struct)와 공용체(union)
System Security Operating System.
9 브라우저 객체 모델.
과제 4: Thread (5월 9일까지) 4장 연습문제 풀이
동적메모리와 연결 리스트 컴퓨터시뮬레이션학과 2016년 봄학기 담당교수 : 이형원 E304호,
엔코더 프로그램 설명 // 쓰레드를 사용하기 때문에 변수와 핸들을 전역변수로 지정 HANDLE hDevice;
1. 지역변수와 전역변수 2. auto, register 3. static,extern 4. 도움말 사용법
Completion Port기반의 채팅프로그램
개정판 누구나 즐기는 C언어 콘서트 제13장 동적 메모리 출처: pixabay.
Power Java 제23장 스레드.
7 생성자 함수.
6 객체.
Presentation transcript:

멀티스레드 Chapter 05. * 학습목표 멀티스레드의 필요성을 이해하고 기본 개념을 익힘. 멀티스레드를 이용하여 TCP 서버를 작성 스레드 동기화 기법을 익힘

프로세스와 스레드 - (1) 용 어 프로세스(process) 메모리를 비롯한 각종 리소스를 담고 있는 컨테이너(container)로서 정적인 개념 스레드(thread) 실제 CPU 시간을 할당받아 수행되는 실행 단위로서 동적인 개념 주 스레드(primary thread) main() 또는 WinMain() 함수에서 시작되는 스레드로, 프로세스가 시작할 때 생성 컨텍스트 전환(context switch) – (뒤에 그림 참조 !) CPU와 운영체제의 협동으로 이루어지는 스레드 실행 상태의 저장과 복원 작업

프로세스와 스레드 - (2) 컨텍스트 전환 과정 CPU ① ② 스레드① 레지스터 스레드② 실행 중지 교환 중지 실행 교환

스레드 생성과 종료 - (1) 스레드 생성에 필요한 요소 프로세스의 주소 공간 f() { ... } main() 코드 주 스레드의 실행 스택 스레드 ①의 코드 스레드 ②의 주 스레드 스레드 ①, ② 스레드 생성에 필요한 요소 스레드 함수(thread function)의 시작 주소 스레드 함수 실행 시 사용할 스택 영역의 크기 프로세스의 주소 공간 2개의 함수 3개의 스레드

스레드 생성과 종료 - (2) CreateThread() 함수 스레드 함수 정의 스레드를 생성한 후 스레드 핸들(thread handle)을 리턴 HANDLE CreateThread ( LPSECURITY_ATTRIBUTES lpThreadAttributes, // NULL SIZE_T dwStackSize, // 0 LPTHREAD_START_ROUTINE lpStartAddress, // 스레드 함수 시작 주소 LPVOID lpParameter, // 스레드 함수 인자(void형 포인터 32비트) DWORD dwCreationFlags, // 0(바로 실행) 또는 CREATE_SUSPENDED(ResumeThread( ) 호출 후 실행 LPDWORD lpThreadId // 스레드 ID(보통 Null값) ) ; 성공: 스레드 핸들, 실패: NULL 스레드 함수 정의 DWORD WINAPI ThreadProc (LPVOID lpParameter) { ... }

스레드 생성과 종료 - (3) 스레드 종료 방법 스레드 종료 함수 ① 스레드 함수가 리턴(많이 사용) ② 스레드 함수 내에서 ExitThread() 함수를 호출(많이 사용) ③ TerminateThread() 함수를 호출(극단적인 경우에만 사용) ④ 주 스레드가 종료하면 모든 스레드가 종료(비추전) 스레드 종료 함수 void ExitThread ( DWORD dwExitCode // 종료 코드 ) ; BOOL TerminateThread ( HANDLE hThread, // 종료할 스레드를 가리키는 핸들 DWORD dwExitCode // 종료 코드 ) ; 성공: 0이 아닌 값, 실패: 0

예제 1 pp. 152 ~ pp. 155 ExThread1.cpp 중요 !

스레드 조작 – 우선 순위 (1) 용 어 스레드 스케줄링(thread scheduling) 윈도우가 각 스레드에게 CPU 시간을 적절히 분배하기 위한 정책 우선순위 클래스(priority class) 프로세스 속성으로, 한 프로세스가 생성한 스레드는 모두 동일한 우선순위 클래스를 가짐 우선순위 레벨(priority level) 스레드 속성으로, 한 프로세스에 속한 스레드 사이에서 상대적인 우선순위를 결정할 때 사용 기초 우선순위(base priority) : 우선순위 클래스 + 우선순위 레벨 우선순위 클래스와 우선순위 레벨을 결합한 값으로, 스레드 스케줄링에 사용

스레드 조작 – 우선 순위 (2) 우선 순위 클래스 (Windows 작업 관리자) 우선 순위 레벨(위와 동일함) 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(낮음) 우선 순위 레벨(위와 동일함) THREAD_PRIORITY_TIME_CRITICAL (실시간) THREAD_PRIORITY_HIGHEST (높음) THREAD_PRIORITY_ABOVE_NORMAL (보통초과) THREAD_PRIORITY_NORMAL (보통) THREAD_PRIORITY_BELOW_NORMAL (보통 아래) THREAD_PRIORITY_LOWEST (낮음) THREAD_PRIORITY_IDLE (없음)

스레드 조작 – 우선 순위 (3) 우선 순위 기반 스레드 스케줄링 ... 스케줄러 (낮음) 기초 우선순위 (높음) CPU 스레드 (낮음) 기초 우선순위 (높음) 3개의 스레드를 교대로 수행

스레드 조작 – 우선 순위 (4) 우선 순위 레벨 조작 함수 BOOL SetThreadPriority ( HANDLE hThread, // 스레드 핸들 int nPriority // 우선순위 레벨값 ) ; 성공: 0이 아닌 값, 실패: 0 int GetThreadPriority ( HANDLE hThread // 스레드 핸들 ) ; 성공: 우선순위 레벨값, 실패: THREAD_PRIORITY_ERROR_RETURN

예제 2 pp. 159 ~ pp. 160 ExThread2.cpp 중요 ! 바이러스 프로그램과 유사함

스레드 조작 – 스레드 종료 대기 (1) WaitForSingleObject() 함수 특정 스레드가 종료할 때까지 대기 WaitForSingleObject() 함수 사용 예 DWORD WaitForSingleObject ( HANDLE hHandle, DWORD dwMilliseconds ) ; 성공: WAIT_OBJECT_0 또는 WAIT_TIMEOUT, 실패: WAIT_FAILED HANDLE hThread = CreateThread(...); WaitForSingleObject(hThread, INFINITE);

스레드 조작 – 스레드 종료 대기 (2) WaitForMultipleObjects() 함수 두 개 이상의 스레드가 종료할 때까지 대기 DWORD WaitForMultipleObjects ( DWORD nCount, const HANDLE* lpHandles, BOOL bWaitAll, DWORD dwMilliseconds ) ; 성공: WAIT_OBJECT_0 ~ WAIT_OBJECT_0 + nCount-1 또는 WAIT_TIMEOUT, 실패: WAIT_FAILED

스레드 조작 – 스레드 종료 대기 (3) WaitForMultipleObjects() 함수 사용 예 ① // 모든 스레드 종료를 기다릴 경우 HANDLE hThread[2]; HANDLE hThread[0] = CreateThread(...); HANDLE hThread[1] = CreateThread(...); WaitForMultipleObjects(2, hThread, TRUE, INFINITE); WaitForMultipleObjects() 함수 사용 예 ② // 두 스레드 중 하나의 종료를 기다릴 경우 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: // 오류 발생 }

스레드 조작 – 실행 중지와 재실행 실행 중지 함수 ① DWORD SuspendThread ( 재실행 함수 DWORD SuspendThread ( HANDLE hThread // 스레드 핸들 ) ; 성공: 중지 횟수, 실패: -1 DWORD ResumeThread ( HANDLE hThread // 스레드 핸들 ) ; 성공: 중지 횟수, 실패: -1 실행 중지 함수 ② 스레드가 실행을 멈추고 일정 시간 동안 대기 void Sleep ( DWORD dwMilliseconds // 밀리초(ms) ) ;

예제 3 pp. 164 ~ pp. 165 ExThread3.cpp 중요 ! 여기까지가 중간고사입니다.

멀티스레드 TCP 서버 - (1) 기본 구조 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; int main(int argc, char* argv[]) // 클라이언트 접속 수용 ① client_sock = accept(listen_sock, ...); // 스레드 생성 ② CreateThread(NULL, 0, ProcessClient, (LPVOID)client_sock, 0, &ThreadId); 기본 구조 뒷 참조! Client IP주소, 포토번호 얻음 부가적인 정보

멀티스레드 TCP 서버 - (2) 소켓과 연관된 주소 정보 얻기 int getpeername ( // 원격 IP주소, 원격 포트번호 리턴 SOCKET s, struct sockaddr* name, int* namelen ) ; 성공: 0, 실패: SOCKET_ERROR int getsockname ( // 지역 IP주소, 지역 포트번호 리턴 SOCKET s, struct sockaddr* name, int* namelen ) ; 성공: 0, 실패: SOCKET_ERROR

예제 4 pp. 168 ~ pp. 173 TCPServer2.cpp 4장의 TCPServer 예제를 수정하여 2개 이상의 Client를 처리하는 예제 4장의 TCPClient 예제는 그대로 사용할 것 ! 중요 !

스레드 동기화 (1) 스레드 동기화(thread synchronization) 필요성 공유 변수 멀티스레드를 사용하는 프로그램에서 두 개 이상의 스레드가 공유 데이터를 접근하는 경우 스레드 1 int money = 1000 ... ① read money into ECX ② ECX = ECX + 2000 ③ write ECX into money 스레드 2 ② ECX = ECX + 4000 공유 변수 Money = 3000 Money = 5000 결국 쓰레드 2의 4000의 값은 없어짐

스레드 동기화 - (2) 다양한 스레드 동기화 기법 종류 주요 용도 임계영역(사용) (critical section) 공유 리소스에 대해 오직 하나의 스레드 접근만 허용 (한 프로세스에 속한 스레드에만 사용 가능) 뮤텍스(Report) (mutex) (서로 다른 프로세스에 속한 스레드에도 사용 가능) – 프로그램 삭제 시 주의(공유파일을 지움?? Yes or No) 이벤트(사용) (event) 특정 사건 발생을 다른 스레드에게 알림 세마포어(Report) (semaphore) 한정된 개수의 자원을 여러 스레드가 사용하려고 할 때, 접근을 제한 대기가능타이머 (waitable timer) (Report) 특정 시간이 되면 대기 중인 스레드를 깨움 중요! (운영체제수업)

스레드 동기화 - (3) 스레드 동기화 원리 매개체 스레드 1 스레드 2 진행 대기 동기화 객체 비신호 상태 신호 상태 P.161 참조(슬라이드 12, 13) WaitForSingleObject WaitForMultipleObject 동기화 객체 비신호 상태 신호 상태 Wait*() 함수로 감지 평소 특정조건이 성립 시 Case, if 구문

임계 영역 - (1) 임계 영역(critical section) 2개 이상의 스레드가 공유 리소스를 접근할 때, 오직 하나의 스레드 접근만 허용해야 하는 경우에 사용 특징 유저(user) 영역 메모리에 존재하는 구조체이므로 한 프로세스에 속한 스레드 동기화에만 사용 가능 일반적인 동기화 객체보다 빠르고 효율적 임계 영역 사용 예 #include <windows.h> CRITICAL_SECTION cs; // ① CRITICAL_SECTION 구조체 변수를 전역 변수로 선언 임계영역은 Application이 직접 메모리 할당 // 스레드 1 DWORD WINAPI Thread1(LPVOID arg) { ... EnterCriticalSection(&cs); // ③ 공유리소스를 사용 X -> 리턴, 공유리소스를 사용 0 -> 대기 // 공유 리소스 접근 LeaveCriticalSection(&cs); // ④ 공유리소스 종료 }

임계 영역 - (2) 임계 영역 사용 예 (계속) // 스레드 2 DWORD WINAPI Thread2(LPVOID arg) { ... EnterCriticalSection(&cs); // ③ // 공유 리소스 접근 LeaveCriticalSection(&cs); // ④ } int main() InitializeCriticalSection(&cs); // ② 임계 영역을 사용하기 전에 이 함수를 호출하여 초기화함. // 스레드 생성과 종료 DeleteCriticalSection(&cs); // ⑤ 임계 영역 사용이 끝나면 이 함수를 호출

예제 5 pp. 178 ~ pp. 182 ExCriticalSection.cpp 임계 영역을 사용하지 않을 경우 문제가 발생하는 극단적인 경우를 예제로 확인 중요 !

이벤트 객체 - (1) 이벤트 객체(event object) 이벤트 객체를 이용한 동기화 예 이벤트 객체 상태 변경 특정 사건 발생을 다른 스레드에게 알릴 때 주로 사용 이벤트 객체를 이용한 동기화 예 ① 이벤트 객체를 비신호 상태로 생성 ② 한 스레드가 작업을 진행하고, 나머지 스레드는 이벤트 객체에 대해 Wait*() 함수를 호출함으로써 이벤트 객체가 신호 상태가 되기를 기다림 ③ 스레드가 작업을 완료하면, 이벤트를 신호 상태로 바꿈 ④ 기다리고 있던 모든 스레드가 깨어나서 작업을 진행 이벤트 객체 상태 변경 이벤트 객체의 종류 자동 리셋(auto-reset) 이벤트 : ResetEvent 함수 사용 않아도 됨 수동 리셋(manual-reset) 이벤트 : ResetEvent 함수 사용해야 함 BOOL SetEvent (HANDLE hEvent) ; // 비신호 상태  신호 상태 BOOL ResetEvent (HANDLE hEvent) ; // 신호 상태  비신호 상태

이벤트 객체 - (2) 이벤트 객체 생성 HANDLE CreateEvent ( LPSECURITY_ATTRIBUTES lpEventAttributes, // 어려움 영역(일단 생략 !!) BOOL bManualReset, // True : 수동리셋이벤트, False : 자동리셋이벤트 BOOL bInitialState, // True : 신호 상태 시작, False : 비신호 상태로 시작 LPCTSTR lpName // Null : 이름없는 이벤트가 생성 ) ; 성공: 이벤트 핸들, 실패: NULL

예제 6 pp. 184 ~ pp. 187 ExEvent.cpp 공유 버퍼에 데이터를 쓰는 쓰레드 1개와 공유 버퍼로부터 데이터를 읽는 쓰레드 2개를 생성하도록 하는 예제 이 경우 1개의 쓰레드만 버퍼를 접근함. 접근 순서도 정해야함. 중요 !