Chapter 4 Multi-Threaded Socket 소켓 프로그래밍
Multi-Threaded Socket 스레드 개념 .NET 에서의 스레딩 스레드 동기화 멀티스레드 소켓 예제 프로그램 실습
스레드 개념 이전까지의 서버는 한번에 하나의 클라이언트만을 처리 여러 클라이언트를 처리할 수 있는 방법이 필요 멀티 스레드 서버를 이용 운영체제 시스템 개념 프로그램 – 명령의 집합 프로세스 – 메모리에 있는 프로그램 (실행된 프로그램) 스레드 가벼운 프로세스 같은 프로세스내의 모든 스레드는 같은 메모리 공간을 공유 프로세스는 스레드와는 달리, 자신만의 메모리 공간을 가짐
프로세스와 스레드 (1/2) 용어 프로세스(process) 스레드(thread) 주 스레드(primary thread) 메모리를 비롯한 각종 리소스를 담고 있는 컨테이너(container)로서 정적인 개념 스레드(thread) 실제 CPU 시간을 할당받아 수행되는 실행 단위로서 동적인 개념 주 스레드(primary thread) main() 또는 WinMain() 함수에서 시작되는 스레드로, 프로세스가 시작할 때 생성 컨텍스트 전환(context switch) CPU와 운영체제의 협동으로 이루어지는 스레드 실행 상태의 저장과 복원 작업
프로세스와 스레드 (2/2) 컨텍스트 전환 과정 CPU ① ② 스레드① 레지스터 스레드②
스레드 개념 윈도우 작업관리자를 통해 스레드 수 확인
스레드 조작 – 우선 순위 (1/3) 용어 스레드 스케줄링(thread scheduling) 윈도우가 각 스레드에게 CPU 시간을 적절히 분배하기 위한 정책 우선순위 클래스(priority class) 프로세스 속성으로, 한 프로세스가 생성한 스레드는 모두 동일한 우선순위 클래스를 가짐 우선순위 레벨(priority level) 스레드 속성으로, 한 프로세스에 속한 스레드 사이에서 상대적인 우선순위를 결정할 때 사용 기초 우선순위(base priority) 우선순위 클래스와 우선순위 레벨을 결합한 값으로, 스레드 스케줄링에 사용
스레드 조작 – 우선 순위 (2/3) 우선 순위 클래스 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(낮음)
스레드 조작 – 우선 순위 (3/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
.NET 에서의 스레딩 예제 프로그램 : SimpleThread.cs Thread 클래스 4개의 생성자 public Thread(ThreadStart) public Thread(ParameterizedThreadStart) public Thread(ThreadStart, int) public Thread(ParameterizedThreadStart, int) 스레드를 생성하기 위해서는 스레드로 실행할 부분의 코드를 따로 분리하여 메서드로 구성해야 함 위의 스레드 생성자는 이 스레드 메서드에 대한 대리자를 인자로 가짐 대리자 대리자란 C나 C++ 에서의 함수 포인터와 같은 역할 스레드 메서드가 인자를 가지지 않는 경우 ThreadStart 대리자를 사용 스레드 메서드가 인자를 가지는 경우 ParameterizedThreadStart 대리자를 사용 마지막 두 개의 생성자는 최대 스택 사이즈를 지정할 수 있는 정수형 인자를 가짐
.NET 에서의 스레딩 스레드 생성 및 시작 (인자가 없는 경우) class SomeClass { void SomeThreadMethod() // Some task to be performed here } void NormalMethod() ThreadStart ts = new ThreadStart(SomeThreadMethod); Thread t = new Thread(ts); t.Start();
.NET 에서의 스레딩 기본적으로 스레드의 생성은 아래와 같이 대리자를 생성 후, 그 대리자를 인자로 하여 스레드를 생성할 수 있지만, 다음과 같이 메서드 이름을 스레드 생성자의 인자로 하여 단축해서 생성이 가능함 ThreadStart ts = new ThreadStart(SomeThreadMethod); Thread t = new Thread(ts); t.Start(); Thread t = new Thread(SomeThreadMethod); t.Start();
.NET 에서의 스레딩 스레드 생성 (단축) class SomeClass { void ThreadWithoutParameter() { // Some task } void ThreadWithParameter(Object data) { ObjParam param = (ObjParam)data; } void NormalMethod() { Thread t1 = new Thread(ThreadWithoutParameter); t1.Start(); // object of user created type ObjParam ObjParam param = new ObjParam(); Thread t2 = new Thread(ThreadWithParameter); t2.Start(param);
스레드 동기화 스레드는 동시에 실행되는 것처럼 보이지만 실제로는 백그라운드 상에서 문맥교환이 아주 빠른 속도로 이루어짐 스레드는 동시에 실행되는 것처럼 보이지만 실제로는 백그라운드 상에서 문맥교환이 아주 빠른 속도로 이루어짐 스레드의 실행순서는 랜덤하게 이루어짐 특정한 경우에는 이러한 랜덤 실행 순서가 바람직하지 못할 수도 있음 경쟁 상태 발생 스레드 동기화가 요구됨
스레드 동기화 예제 프로그램 : RaceCondition.cs 같은 프로세스에 속한 모든 스레드는 같은 메모리 공간을 공유 같은 프로세스에 속한 모든 스레드는 같은 메모리 공간을 공유 이러한 특징으로 인해 스레드 간의 정보교환이 쉽게 이루어질 수 있음 하지만, 한 스레드가 다른 스레드에 의해 사용되고 있는 변수를 수정할 경우 문제가 발생 경쟁 상태 발생 경쟁 상태를 예방하기 위해 스레드의 동기화가 필요 크리티컬 섹션 동시에 접근할 수 없는 코드 구역
스레드 동기화 스레드 동기화 기술 크리티컬 섹션에 대한 스레드의 접근을 동기화 Exclusive Lock (lock) 한 스레드가 락을 획득하면, 나머지 스레드는 차단 락이 해제될 때까지 대기 예제 프로그램 : RaceConditionLock.cs Monitor 메서드 호출과 try…finally 블록을 이용하여 락을 획득하고 해제 Monitor.Enter(), Monitor.Exit() 예제 프로그램 : RaceConditionMonitor.cs Mutual Exclusion (Mutex) 뮤텍스 알고리즘 이용 mutex.WaitOne(), mutex.ReleaseMutex() 예제프로그램 : RaceConditionMutex.cs
멀티 스레드 소켓 리스너 소켓 프로세스 흐름
멀티 스레드 소켓 TCP 소켓 리스너는 접속을 수락한 후 다시 리스닝 상태로 돌아감 소켓을 종단점에 바인딩 한 후, 들어오는 요청에 대해 리스닝을 시작 클라이언트가 서버로 접속을 시도하면, 서버는 이 요청을 수락하고 클라이언트와 통신을 하기 위한 새로운 소켓 객체를 생성 접속 수락 후에 리스너 소켓은 다시 리스닝 상태로 돌아가서 또 다른 접속 요청을 대기 단일 스레드 환경에서는 서버가 한 클라이언트의 요청을 처리하기에 바빠서 또 다른 요청을 처리할 수 있는 제어방법을 가지고 있지 않음 이러한 한계를 극복하기 위해 멀티 스레드 소켓을 구현
멀티 스레드 소켓 멀티 스레드 서버
멀티 스레드 소켓 멀티 스레드 서버 크게 두 부분으로 구성 리스닝 접속 수락 후 클라이언트와의 통신 처리 클라이언트와의 통신을 위해 소켓을 생성하여 통신을 처리하는 부분을 스레드 메서드로 구현 리스너는 접속 수락 후 클라이언트와의 통신을 위한 새로운 소켓을 생성한 후, 리스닝 상태에 남아 또 다른 요청이 있을 경우 동일한 작업을 수행
예제 프로그램 실습 향상된 에코 서버: EchoServerMT.cs 예제 프로그램 이전 챕터의 싱글 스레드 클라이언트를 이용하여 실습 하나 이상의 클라이언트 실행 예제 프로그램 DirectoryServer.cs DirectoryClient.cs