반응형
728x90
반응형

진짜 다 까먹어서 다시 예제 쳐보고 다시 올린다... 정말 미리미리 올리고 자주자주 봐야합니다..

포스팅 순서가 사실 멀티 프로세싱이 먼저이지만, 게임 서버 개발에 사용한 것은 멀티 플렉싱 모델이었기 때문에 먼저 올렸었는데, 사실 멀티 프로세싱이 무엇인지, 그리고 그 단점이나 필요한 영역은 어느 부분인지 알아야 한다.

그래서 포스팅을 또 하게 되었다.

내가 구현했던 서버의 모델은 멀티 플렉싱 모델이었다(select, epoll) 이 모델은 위와 같은 구조로 이루어진다.

여러 학생들이 클라이언트들이고, 교사하나프로세스이다.
질의와 답변을 필요로 하는 학생들, 즉 송수신을 요청하는 애들만 빠른 반복문 처리를 통해 처리한다.

이러한 모델에서는 여러 명의 클라이언트들이 송수신이나 연결 등의 여러 요청을 할 때마다 그 요청만큼만 처리하는 구조이기 때문에 대용량의 파일을 송수신하는 연결과는 적합하지 않다. 

반면, 멀티 프로세싱 모델은 다음과 같다.

교사들 프로세스들이고, 여러 학생들이 클라이언트들인것이다.
학생들이 질의와 답변을 필요로 하든 안 하든 무조건 프로세스와 연결되어 1대1 통신이 진행되는 것이다.

이런 구조에서는 시간이 오래 걸리는 상담이나 컨설팅 같은 서비스가 교사와 학생들 사이에서 제공되어야 할 법하다. 마찬가지로 프로세스-클라이언트 입장에서 봤을 때, 용량이 크고 시간이 오래 걸리는 파일 전송 등이 자원 효율이 클 것이다.

이러한 멀티 프로세싱 기반의 소켓을 작성하기 위해서는 fork() 에 대한 개념이 필요하다.

그전에! 프로세스란 무엇인가?

운영체제 관점에서 별도의 실행 흐름을 구성하는 단위. 
생성될 때, PCB(Process Controll Block) 라고 하는 프로세스에 대한 정보 구조가 생성되며,
이 정보에는 해당 프로세스에 대한 구체적인 정보들이 저장된다
(메모리 할당, 파일 디스크립터 테이블 등등 수 많은..)

프로세스의 복사본을 생성하는 fork()

위와 같은 기본 코드가 있다. 10번 줄을 보면 fork 라는 함수를 호출한다. 이 fork() 함수프로세스를 그대로 복사하는 함수이다. 이 함수가 호출되는 순간!! 프로세스가 그대~로 복사되어 10번 라인부터는 흐름이 각각 따로 진행된다. 다음과 같이 말이다.

그렇다면 이 함수가 반환하는 값은 무엇일까? 원래 실행되던 흐름부모 프로세스라고 하고, 복사된 실행 흐름자식 프로세스라고 한다.

부모 프로세스의 실행 흐름일 때, 10번 라인에서 반환되는 값은 자식 프로세스의 프로세스 ID 번호이다.
자식 프로세스의 실행 흐름일 때, 10번 라인에서 반환되는 값은 무조건 0이다.

그래서 12번 라인과 16번 라인에서는 부모 프로세스와 자식 프로세스의 실행 흐름을 구별하기 위해 pid를 0인지 아닌지를 비교하고 각 실행 흐름에 맞는 처리를 진행하면 된다.

 

이런 식으로 프로세스를 생성하므로, 클라이언트가 접속하면 프로세스를 복사하여 클라이언트에게 할당해줘서 송수신처리를 담당하면 된다. 

그런데.. 이러한 방식에는 큰 문제가 있었으니..

 

이번 포스팅에서 제일 중요한 것은 프로세스의 복사는 아예 메모리까지 통채로 복사되어
실행 흐름이 완전 다른 별개로 나뉘어진 부모 프로세스, 자식 프로세스라는 것이다!

728x90
반응형
728x90
반응형

자, 오늘도 기록을 한다 

지난 포스팅들을 보면 select 모델들을 학습했다. 그런데 이 select 모델은 굉장한 단점들이 있다고 하더라..

단점들로 인해서 발생하는 현상부터 말하자면 다음과 같다.

클라이언트를 동시에 수용할 수 있는 수가 100 을 넘기가 힘들다.

뭐 나처럼 프리 서버나 만드는 수준이라면 상관없겠지만, 그래도 100명은 너무 적지 않나 싶다. 그렇다면 왜 그런지 알아보자.

Select 모델의 단점

1. select 반환 값에 따라 행동을 할 때, 등장하는 등록된 파일 디스크립터들을 대상으로 하는 반복문

이게 첫 번째 문제이다. 아래 코드를 보면 된다.

55번 라인에서 select 함수를 호출한 뒤 반환되는 값에 따라서 변화한 파일 디스크립터의 수만큼 반복 루프를 도는 것도 아니고, 전체 등록된 파일 디스크립터의 수만큼 반복 루프 및 조건 검사를 진행한다.

이 말인 즉슨, 파일 디스크립터가 딱 하나 변한다고 하더라도 전체를 검사한다는 소리이다. -> 매우 비효율적이다.

2. Select 함수를 호출할 때마다 관찰 대상의 인자 전달.

위 그림에서 51번 라인에서 등록된 파일 디스크립터들을 최신화하고, 55번 라인에서 select 함수의 인자로 전달을 한다. 이러한 인자 전달은 select 함수 내에서만 사용되고 마는 것이 아니다. 

파일 디스크립터의 변화를 파악한다는 것은 수신 버퍼, 쓰기 버퍼 등을 확인하는 작업이기 때문에 운영체제의 관리 대상이다. 운영체제의 도움이 필요한 것이다.  즉, 전달된 인자를 운영체제에게까지 전달하여 운영체제의 도움을 받아야 한다는 소리인데..

응용 프로그램 단에서 운영체제에게 이렇게 많은 데이터를 전달한다는 것은 부담이 크다고 한다. 

그래서 운영체제에게 관찰 대상에 대한 정보를 초기에 한 번 알려주고, 갱신되는 부분에 대해서만 알려주는 방식을 사용하면 되지않을까 라는 생각에서 나온 것이 Epoll 방식이다. 윈도우에서는 IOCP 라는 개념으로 발전되었다고 한다.

다음 번 포스팅은 Epoll 이다. Epoll 모델이 기존 Select 모델에 비해 무엇이 달라졌는지 정도 확인과 작성 코드를 분석하는 시간을 갖겠다.

 

 

 

728x90
반응형

+ Recent posts