728x90

멀티 프로세스 기반 프로그램

서버와 접속용 클라이언트 프로그램이 있다고 가정할 때, 일반 사용자들은 서버 접속용 클라이언트 프로그램을 통해 서버에 접속하여 특정 서비스를 요청한다. 서버는 이러한 요구를 처리하기 위해서 요청이 있을때 마다 자식 프로세스를 생성한다. 동시에 둘 이상의 접속자에게 원할한 서비스를 제공해 주기 위함이다.

 

멀티프로세스 운영체제 기반 프로그램의 문제점과 새로운 제안

둘 이상의 실행 흐름을 위해 프로세스를 추가적으로 생성하는 작업은 매우 부담스럽다. 많은 수의 프로세스 생성은 빈번한 컨텍스트 스위칭(Context Switching)으로 이어져 성능에 영향을 줄 수 있다.

 

컨텍스트 스위칭 : 프로세스의 상태 정보를 저장하고 복원하는 일련의 과정이다.

 

컨텍스트 스위칭의 빈도수는 시스템에 따라 다르지만 못해도 초당 수십회 이상 발생한다. 따라서 이러한 컨텍스트 스위칭은 성능 저하의 원인이 된다.

 

하나의 프로그램 내에서 둘이상의 실행흐름을 두기 위해 등장한 것이 쓰레드이다. 쓰레드는 프로세스 처럼 각각 독립된 구조가 아니다. 즉 쓰레드들 사이에는 공유하는 요소들이 있다. 쓰레드는 공유하는 요소가 있어서 컨텍스트 스위칭에 걸리는 시간이 프로세스보다 짧다.

 

쓰레드를 생성할 때마다 해당 쓰레드의 스택은 새로 생성해주고, Code 영역, Data 영역, Heap영역은 부모 쓰레드와 공유한다.

 

쓰레드의 특성 1 : 쓰레드마다 스택을 독립적으로 할당해준다. 쓰레드는 Code영역, Data영역, Heap영역을 공유하고 Stack영역은 독립적으로 할당된다. 스택은 함수호출시 전달되는 인자, 되돌아갈 주소 값 및 함수 내에서 선언하는 변수등을 저장하기 위한 메모리 공간이다. 이 메모리 공간이 독립적이라는 뜻은 추가적인 실행 흐름을 만들 수 있다는 의미가 된다. 즉 실행 흐름의 추가를 위한 최소조건이 독립된 스택의 제공이다.

 

쓰레드의 특성 2 : 코드영역을 공유한다.

위 그림은 코드영역을 공유하는 것을 보여준다. 프로세스 main 하나와 쓰레드 main 두개가 있다. 결과적으로 프로그램의 실행 흐름은 총 3개가 된다.

 

쓰레드의 특성 3 : 데이터 영역과 힘을 공유한다.

쓰레드간에 힙과 데이터 영역을 공유하기 때문에 힙이나 데이터 영역을 통해 쓰레드 간에 서로 통신하는 것이 가능하다. 즉 전역변수와 malloc 함수를 통해서 동적 할당된 메모리 공간은 공유가 가능하다.

데이터 영역과 힙의 공유가 좋은것만은 아니다. 메모리 영역을 공유하다 보면 문제가 발생할 수도 있기 때문이다.

 

컨텍스트 스위칭이 빨라진 쓰레드

쓰레드 컨텍스트 스위칭은 프로세스 컨텍스트 스위칭에 비해 빠르다. 그 이유는 공유하는 영역이 많아서 이다.

또한 세부적인 요소들에는 레지스터들이 있다.

PC(Program Counter) : PC는 다음 실행해야할 명령어의 위치를 가리킨다. 쓰레드는 코드영역을 공유하기 때문에 PC는 컨텍스트 스위칭을 하더라도 영향이 없을거라고 생각하기 쉽다. 그러나 PC는 프로그램 실행 흐름과 관련이 있다. 쓰레드 별로 main 함수를 독립적으로 가지고 있고, 함수 호출도 독립적으로 진행되기 때문에 쓰레드별로 PC가 가져야할 값이 다르다. 그렇기 때문에 쓰레드 컨텍스트 스위칭에서 PC는 프로세스 컨텍스트 스위칭과 같다.

 

fp(Frame Pointer), SP(Stack Pointer) : 쓰레드별로 별도의 스택을 가지고 있기 때문에 fp, spp 의 경우도 컨텍스트 스위칭이 발생한다.

 

범용 레지스터 : 보통 연산을 위해 임시 데이터 저장소로 쓰인다. 연산은 프로그램 흐름에 따라 진행되므로 당연히 컨텍스트 스위칭 시 레지스터들도 컨텍스트 스위칭이 발생한다. 그러나 전역으로 선언된 변수를 할당 하기로 결정하였다면, 쓰레드의 컨텍스트 스위칭시 전혀 영향을 받지 않을 것이다.

 

Windows에서의 프로세스와 쓰레드

Window에서 프로세스는 쓰레드를 담는 상자이다. 실제 프로그램의 흐름을 형성하는 것은 쓰레드 이기 때문이다. window 운영체제에서 프로세스는 상태(Running, Ready, Blocked)를 지니지 않는다. 상태를 지니는 것은 프로세스가 아니라 쓰레드이다.

 

즉 쓰레드가 입출력에 관한 연산을 할 경우 Blocked상태에 놓이게 된다. 쓰레드는 입출력 연산이 끝나면 Ready상태가 되고, 그다음  Running 상태가 된다.

스케줄링 알고리즘 또한 프로세스가 아닌 쓰레드 기반으로 작동한다.

 

728x90

+ Recent posts