10-1. 다중접속서버의 필요성과 멀티프로세스 [TCP/IP][C][LINUX]
서버가 한 번에 한 요청만 받을 수 있다면 연결요청이 무수히 쌓였을 때 후순위에 있는 요청은 받아들여지기까지 긴 시간이 걸릴 것입니다. 또, 네트워크 프로그램은 데이터의 송수신 시간이 큰 비중을 차지하기에 한 번에 한 요청보단 여러 요청을 받는 것이 더 유리합니다. 그래서 둘 이상의 클라이언트에게 동시에 서비스를 제공하는 다중접속 서버가 필요합니다.
멀티프로세스 기반 서버 : 다수의 프로세스를 생성하는 방식
멀티플렉싱 기반 서버 : 입출력 대상을 묶어서 관리하는 방식
멀티쓰레딩 기반 서버 : 클라이언트의 수만큼 쓰레드를 생성하는 방식
위는 대표적인 세 가지 다중접속 서버입니다. 이 문서에서는 제목에서 말했듯 멀티프로세스 기반 서버에 대해서 다룰 것입니다.
먼저 프로세스란, 메모리 공간을 차지한 상태에서 실행중인 프로그램을 뜻합니다. 프로그램을 실행하면 프로그램은 메인 메모리라는 곳으로 이동하고 실행을 위한 준비를 마치는데 이 시점부터 프로세스라 부를 수 있습니다. 만약 동일 프로그램을 둘 이상 킨다면 프로세스는 실행한 수만큼 생성됩니다. 또 프로세스는 생성될때 ID를 부여받는데, 1은 운영체제의 실행에 필요한 프로세스고, 나머지는 2 이상의 정수 형태를 띠게 됩니다.
따라서 프로그램을 여러 개 실행하면 프로세스도 그만큼 생성되고, 각 프로세스는 당연하게도 동시에 실행됩니다. 그러나 하나의 프로그램에서 여러 개의 프로세스가 생성되곤 하는데 멀티프로세스 기반 서버가 이 예시입니다.
#include<unistd.h>
pid_t fork(void);
//success: 프로세스ID fail: -1
멀티프로세스 기반 서버 구현에는 fork()라는 함수를 이용합니다. 이 함수를 호출하면 호출한 프로세스의 복사본을 생성합니다. 그러고 나서 현재 프로세스와 복사한 프로세스 모두 fork 함수 호출 및 반환 이후 문장을 실행하게 됩니다. 그리고 메모리 영역 또한 복사하기에 이후 프로그램 흐름은 fork 함수의 반환 값을 기준으로 나뉘도록 짜야합니다.
위 코드블럭에서 함수의 반환 값이 프로세스 ID라고 했는데, 이는 부모 프로세스에서의 반환 값이고 자식 프로세스에서는 0을 반환하게 됩니다.
pid_t pid=fork();
if(pid==0){
//자식 프로세스에서 실행
}
else{
//부모 프로세스에서 실행
}
따라서 위와 같이 fork()의 반환 값에 따른 부모 프로세스와 자식 프로세스의 실행을 나눠줄 수 있습니다.