6장. 멀티스레드 멀티스레드 프로그래밍의 필요성을 이해하고 기본 개념을 익힌다.

Slides:



Advertisements
Similar presentations
1 ‘ 우리나라의 주요공업 ’ - 정도웅, 주민혁, 안수진, 백경민, 엄다운, 박경찬 -.
Advertisements

TCP 서버/클라이언트 동작 원리 - (1) TCP 서버/클라이언트 예 웹 서버 웹 클라이언트 웹 클라이언트
contents Thread function Create Thread Terminate Thread
공부할 내용 조상들이 살던 곳 자연과 잘 어울리는 한옥 지방에 따라 서로 다른 집의 모양 섬 지방의 집
사랑, 데이트와 성적 자율성 :데이트 성폭력!!! 성폭력예방교육 전문강사 / 여성학 전공 신 순 옥.
2016 ITA 1월 강의 C Programming -4일차- 포인터배열 및 이중포인터 정대진 ( )
Chapter 09. 소켓 입출력 모델(I).
퇴계와 율곡의 사회사상 비교 남 일 재 동서대학교 교수/ 정치학 박사 1. 퇴계 이황과 율곡 이이의 약전(略傳)
13장 소켓.
Chapter 06. UDP 서버/클라이언트.
501. 군인들의 세상 502. 민정 이양과 한일회담 이선용.
Department of Computer Engineering
인공지능실험실 석사 2학기 김승겸 TCP/IP Socket Programming… 제 10장 멀티태스킹 기반의 서버구현 인공지능실험실 석사 2학기 김승겸
Signal & Inter-Process Communication
디바이스 드라이버 기초 디바이스 드라이버의 개요 파일 연산 디바이스 드라이버 등록 디바이스 드라이버 구성
디바이스 드라이버 개요 가상 디바이스드라이버 실습
Department of Computer Engineering
Multi-thread Programming
스레드의 개념과 동작 원리를 이해한다. MFC 스레드의 두 종류인 작업자 스레드와 UI 스레드 사용법을 익힌다.
MultiThread.
TCP Client/Server Program
Network Lab. Seoung Hyeon, Lee
얇지만 얇지 않은 TCP/IP 소켓 프로그래밍 C 2판
6 프로세스 생성과 실행.
Chapter 11. Raw 소켓.
Linux System Programming
3장. 소켓 주소 구조체 다루기 소켓 주소 구조체의 정의와 초기화 방법을 익힌다.
6장 비연결형 지향 프로토콜 Database Lab 강 우 석.
14장 소켓.
제 12장 I/O멀티플렉싱(Multiplexing)
Using Standard I/O on Sockets
Department of Computer Engineering
Chapter 02. 윈도우 소켓 시작하기.
데이터베이스 실험실 석사 2학기 김기훈 TCP/IP Socket Programming… 제 17장 멀티쓰레드 기반의 서버구현 데이터베이스 실험실 석사 2학기 김기훈
Department of Computer Engineering
멀티쓰레드 기반의 서버구현 School of Electronics and Information.
Department of Computer Engineering
Term Project Team Member
7장. UDP 서버-클라이언트 UDP 서버-클라이언트의 기본 구조와 동작 원리를 이해한다.
Department of Computer Engineering
Chapter 12. 직렬 통신과 무선 프로토콜.
(ioctl, mmap, fsync&flush)
프로그래밍2 및 실습 C언어 기반의 C++ 2.
Department of Computer Engineering
7장. UDP 서버-클라이언트 UDP 서버-클라이언트의 기본 구조와 동작 원리를 이해한다.
멀티스레드 Chapter 05. * 학습목표 멀티스레드의 필요성을 이해하고 기본 개념을 익힘.
컴퓨터 개론 및 실습 Dept. Computer Eng. Hankuk University of Foreign Studies
Signal & Inter-Process Communication
Chapter 09. 소켓 입출력 모델(I).
컴퓨터의 기초 제 2강 - 변수와 자료형 , 연산자 2006년 3월 27일.
네트워크 프로그래밍의 이해 School of Electronics and Information.
WSAAsync Select 김대열 Bit - Academy Sunmoon University, Korea.
데이터베이스실험실 석사 2학기 조정희 TCP/IP Socket Programming… 제 19장 윈도우 기반의 쓰레드 동기화 데이터베이스실험실 석사 2학기 조정희
4장 - PHP의 표현식과 흐름 제어-.
데이터베이스실험실 석사 2학기 조정희 TCP/IP Socket Programming… 제 18장 윈도우 기반 쓰레드 사용하기 데이터베이스실험실 석사 2학기 조정희
3장. 변수와 연산자. 3장. 변수와 연산자 3-1 연산자, 덧셈 연산자 연산자란 무엇인가? 연산을 요구할 때 사용되는 기호 ex : +, -, *, / 3-1 연산자, 덧셈 연산자 연산자란 무엇인가? 연산을 요구할 때 사용되는 기호 ex : +, -, *, /
정치개혁의 가능성 논의 권력구조 개편을 통하여 본 -개헌을 통한 정부형태의 변화를 중심으로 [한국정치론] 윤성이 교수님
Department of Computer Engineering
Department of Computer Engineering
노년기 발달 장안대 행정법률과 세류반 정 오 손
Chapter 04. TCP 서버/클라이언트.
태국 문학 욜라다 왓짜니 싸란차나 팟차라와라이 끼따야펀 르앙다우 타니다.
컴퓨터 프로그래밍 기초 - 11th : 파일 입출력 및 구조체 -
실습과제 1번 생성된 파일 basic.txt를 프로젝트 폴더에서 메모장으로 열고 내용을 확인
워밍업 실뭉치 전달게임.
argc, argv 의 사용방법 #include <stdio.h>
Signal & Inter-Process Communication
C 13장. 입출력 라이브러리 #include <stdio.h> int main(void) { int num;
음파성명학 최종욱.
Department of Computer Engineering
Presentation transcript:

6장. 멀티스레드 멀티스레드 프로그래밍의 필요성을 이해하고 기본 개념을 익힌다. 멀티스레드를 이용해 다중 클라이언트 처리가 가능한 서버를 작성할 수 있다. 스레드 동기화 기법을 이해하고 활용할 수 있다.

TCP 서버-클라이언트의 문제점 (1) 문제 ①: 동시에 둘 이상의 클라이언트 서비스 불가

TCP 서버-클라이언트의 문제점 (2) 문제 ① 해결책 서버가 각 클라이언트와 통신하는 시간을 짧게 줄임 장점: 구현이 쉬움, 가장 적은 시스템 자원 사용 단점: 각 클라이언트의 처리 지연 시간이 길어질 수 있음 각 클라이언트를 스레드를 이용해 독립적으로 처리 장점: 소켓 입출력 모델에 비해 구현이 쉬움 단점: 가장 많은 시스템 자원 사용 소켓 입출력 모델 사용(10~11장) 장점: 소수의 스레드를 이용해 다수의 클라이언트를 처리 ⇒ 상대적으로 적은 시스템 자원 사용 단점: 구현이 어려움

TCP 서버-클라이언트의 문제점 (3) 문제 ②: 교착 상태 발생 가능성 TCP 서버 ... recv(...); send(...); TCP 클라이언트 여기서 대기! (교착 상태)

TCP 서버-클라이언트의 문제점 (4) 문제 ② 해결책 데이터 송수신 부분 잘 설계하기 소켓에 타임아웃 옵션 적용하기 장점: 특별한 기법 없이 곧바로 구현 가능 단점: 모든 경우에 대한 해결책은 될 수 없음 소켓에 타임아웃 옵션 적용하기 장점: 구현이 쉬움 단점: 다른 방법에 비해 성능이 낮음 넌블로킹 소켓 사용하기 장점: 근본적으로 교착 상태 해결 단점: 구현이 복잡, 시스템 자원(특히 CPU 시간) 낭비 소켓 입출력 모델 사용(10~11장) 장점: 넌블로킹 소켓의 단점을 보완 & 교착 상태 해결 단점: 첫 번째나 두 번째 해결책보다 구현이 어려움

프로세스와 스레드 (1) 용어 프로세스 스레드 주 스레드 or 메인 스레드 코드, 데이터, 리소스를 파일에서 읽어들여 윈도우 운영체제가 할당해놓은 메모리 영역에 담고 있는 일종의 컨테이너로 정적인 개념 스레드 CPU 시간을 할당받아 프로세스 메모리 영역에 있는 코드를 수행하고 데이터를 사용하는 동적인 개념 주 스레드 or 메인 스레드 응용 프로그램 실행 시 최초로 생성되는 스레드 WinMain() 또는 main() 함수에서 실행 시작

프로세스와 스레드 (2) 멀티스레드 동작 원리 CPU ① ② 스레드① 레지스터 스레드②

스레드 생성과 종료 (1) 스레드 생성에 필요한 요소 스레드 함수의 시작 주소 스레드 함수 실행 시 사용할 스택의 크기 f() { ... } main() 주 스레드의 실행 스택 스레드①의 코드 스레드②의 주 스레드 스레드①, ②

스레드 생성과 종료 (2) CreateThread() 함수 스레드 생성 후 스레드 핸들을 리턴 HANDLE CreateThread ( LPSECURITY_ATTRIBUTES lpThreadAttributes, // NULL SIZE_T dwStackSize, // 0 LPTHREAD_START_ROUTINE lpStartAddress, // 스레드 함수 LPVOID lpParameter, // 스레드 함수에 전달할 인자 DWORD dwCreationFlags, // 0 또는 CREATE_SUSPENDED LPDWORD lpThreadId // 스레드 ID ) ; 성공: 스레드 핸들, 실패: NULL

스레드 생성과 종료 (3) 스레드 함수 형태 DWORD WINAPI ThreadProc(LPVOID lpParameter) { ... }

스레드 생성과 종료 (4) 스레드 종료 방법 ① 스레드 함수가 리턴 ② 스레드 함수 내에서 ExitThread() 함수를 호출 ③ 다른 스레드가 TerminateThread() 함수를 호출 ④ 주 스레드가 종료하면 모든 스레드가 종료

스레드 생성과 종료 (5) 스레드 종료 함수 void ExitThread ( DWORD dwExitCode // 종료 코드 ) ; BOOL TerminateThread ( HANDLE hThread, // 종료할 스레드를 가리키는 핸들 DWORD dwExitCode // 종료 코드 ) ; 성공: 0이 아닌 값, 실패: 0

스레드 제어 – 우선순위 변경 (1) 용어 스레드 스케줄링 or CPU 스케줄링 우선순위 클래스 우선순위 레벨 기본 우선순위 프로세스 속성으로, 같은 프로세스가 생성한 스레드는 우선순위 클래스가 모두 같음 우선순위 레벨 스레드 속성으로, 같은 프로세스에 속한 스레드 간 상대적인 우선순위를 결정할 때 사용 기본 우선순위 우선순위 클래스와 우선순위 레벨을 결합한 값으로, 스레드 스케줄링에 사용

스레드 제어 – 우선순위 변경 (2) 우선순위 클래스 REALTIME_PRIORITY_CLASS(실시간) HIGH_PRIORITY_CLASS(높음) ABOVE_NORMAL_PRIORITY_CLASS(높은 우선순위; 윈도우2000 이상) NORMAL_PRIORITY_CLASS(보통) BELOW_NORMAL_PRIORITY_CLASS(낮은 우선순위; 윈도우2000 이상) IDLE_PRIORITY_CLASS(낮음)

스레드 제어 – 우선순위 변경 (3) 우선순위 레벨 THREAD_PRIORITY_TIME_CRITICAL THREAD_PRIORITY_HIGHEST THREAD_PRIORITY_ABOVE_NORMAL THREAD_PRIORITY_NORMAL THREAD_PRIORITY_BELOW_NORMAL THREAD_PRIORITY_LOWEST THREAD_PRIORITY_IDLE

스레드 제어 – 우선순위 변경 (4) 윈도우의 스레드 스케줄링 방식 (낮음) 기본 우선순위 (높음) ... 세 개의 스레드를 스케줄러 CPU 스레드 (낮음) 기본 우선순위 (높음) 세 개의 스레드를 번갈아 수행

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

스레드 제어 – 스레드 종료 기다리기 (1) WaitForSingleObject() 함수 특정 스레드가 종료할 때까지 기다리기 WaitForSingleObject() 함수 사용 예 DWORD WaitForSingleObject ( HANDLE hHandle, DWORD dwMilliseconds ) ; 성공: WAIT_OBJECT_0 또는 WAIT_TIMEOUT, 실패: WAIT_FAILED HANDLE hThread = CreateThread(...); DWORD retval = WaitForSingleObject(hThread, 1000); if(retval == WAIT_OBJECT_0) { ... } // 스레드 종료 else if(retval == WAIT_TIMEOUT) { ... } // 타임아웃(스레드는 아직 종료 안 함) else { ... } // 에러 발생

스레드 제어 – 스레드 종료 기다리기 (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);

스레드 제어 – 스레드 종료 기다리기 (4) 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: // 오류 발생 }

스레드 제어 – 실행 중지와 재실행 (1) 실행 중지 함수 ① 재실행 함수 DWORD SuspendThread ( HANDLE hThread // 스레드 핸들 ) ; 성공: 중지 횟수, 실패: -1 DWORD ResumeThread ( HANDLE hThread // 스레드 핸들 ) ; 성공: 중지 횟수, 실패: -1

스레드 제어 – 실행 중지와 재실행 (2) 실행 중지 함수 ② void Sleep ( DWORD dwMilliseconds // 밀리초(ms) ) ;

멀티스레드 TCP 서버 (1) 기본 구조 DWORD WINAPI ProcessClient(LPVOID arg) { // ③ 전달된 소켓 저장 SOCKET client_sock = (SOCKET)arg; // ④ 클라이언트 정보 얻기 addrlen = sizeof(clientaddr); getpeername(client_sock, (SOCKADDR *)&clientaddr, &addrlen); // ⑤ 클라이언트와 데이터 통신 while(1){ ... }

멀티스레드 TCP 서버 (2) 기본 구조(계속) int main(int argc, char *argv[]) { ... while(1){ // ① 클라이언트 접속 수용 client_sock = accept(listen_sock, ...); // ② 스레드 생성 CreateThread(NULL, 0, ProcessClient, (LPVOID)client_sock, 0, NULL); }

멀티스레드 TCP 서버 (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

스레드 동기화 (1) 스레드 동기화 필요성 스레드 1 스레드 2 공유 변수 int money = 1000 ... ① read money into ECX ② ECX = ECX + 2000 ③ write ECX into money 스레드 2 ② ECX = ECX + 4000 공유 변수

스레드 동기화 (2) 스레드 동기화 기법 종류 기능 임계 영역 공유 자원에 대해 오직 한 스레드의 접근만 허용 (한 프로세스에 속한 스레드 간에만 사용 가능) 뮤텍스 (서로 다른 프로세스에 속한 스레드 간에도 사용 가능) 이벤트 사건 발생을 알려 대기 중인 스레드를 깨움 세마포어 한정된 개수의 자원에 여러 스레드가 접근할 때, 자원을 사용할 수 있는 스레드 개수를 제한 대기 가능 타이머 정해진 시간이 되면 대기 중인 스레드를 깨움

스레드 동기화 (3) 스레드 동기화가 필요한 상황 스레드 동기화 원리 ① 둘 이상의 스레드가 공유 자원에 접근 ② 한 스레드가 작업을 완료한 후, 기다리고 있는 다른 스레드에 알림 스레드 동기화 원리 스레드 1 매개체 스레드 2 진행 대기

스레드 동기화 (4) (스레드) 동기화 객체의 특징 Create*( ) 함수를 호출하면 커널 메모리 영역에 동기화 객체가 생성되고, 이에 접근할 수 있는 핸들이 리턴됨 평소에는 비신호 상태로 있다가 특정 조건이 만족되면 신호 상태가 됨. 비신호 상태에서 신호 상태로 변화 여부는 Wait*( ) 함수를 사용해 감지(다음 페이지 그림 참조) 사용이 끝나면 CloseHandle( ) 함수를 호출

스레드 동기화 (5) 동기화 객체의 상태 변화 동기화 객체 비신호 상태 신호 상태 Wait*() 함수로 감지

임계 영역 (1) 임계 영역 둘 이상의 스레드가 공유 자원에 접근할 때, 오직 한 스레드만 접근을 허용해야 하는 경우에 사용 특징 프로세스의 유저 메모리 영역에 존재하는 단순한 구조체이므로 한 프로세스에 속한 스레드 간 동기화에만 사용 일반 동기화 객체보다 빠르고 효율적

임계 영역 (2) 임계 영역 사용 예 #include <windows.h> CRITICAL_SECTION cs; DWORD WINAPI MyThread1(LPVOID arg) { ... EnterCriticalSection(&cs); // 공유 자원 접근 LeaveCriticalSection(&cs); } DWORD WINAPI MyThread2(LPVOID arg)

임계 영역 (3) 임계 영역 사용 예(계속) EnterCriticalSection(&cs); // 공유 자원 접근 LeaveCriticalSection(&cs); ... } int main(int argc, char *argv[]) { InitializeCriticalSection(&cs); // 둘 이상의 스레드를 생성하여 작업을 진행한다. // 생성한 모든 스레드가 종료할 때까지 기다린다. DeleteCriticalSection(&cs);

이벤트 (1) 이벤트 이벤트를 사용하는 전형적인 절차 사건 발생을 다른 스레드에 알릴 때 사용 ➊ 이벤트를 비신호 상태로 생성 ➋ 한 스레드가 작업을 진행하고, 나머지 스레드는 이벤트에 대해 Wait*( ) 함수를 호출해 이벤트가 신호 상태가 될 때까지 대기 ➌ 스레드가 작업을 완료하면 이벤트를 신호 상태로 바꿈 ➍ 기다리고 있던 스레드 중 하나 혹은 전부가 깨어남

이벤트 (2) 이벤트 상태 변경 이벤트의 종류 자동 리셋 이벤트 수동 리셋 이벤트 이벤트를 신호 상태로 바꾸면, 기다리는 스레드 중 하나만 깨운 후 자동으로 비신호 상태가 됨 수동 리셋 이벤트 이벤트를 신호 상태로 바꾸면, 기다리는 스레드를 모두 깨운 후 계속 신호 상태를 유지함 BOOL SetEvent(HANDLE hEvent); // 비신호 상태  신호 상태 BOOL ResetEvent(HANDLE hEvent); // 신호 상태  비신호 상태

이벤트 (3) 이벤트 생성 HANDLE CreateEvent ( LPSECURITY_ATTRIBUTES lpEventAttributes, BOOL bManualReset, BOOL bInitialState, LPCTSTR lpName ) ; 성공: 이벤트 핸들, 실패: NULL

Thank you www.hanb.co.kr TCP/IP 윈도우 소켓 프로그래밍