다중접속 서버의 종류
- 둘 이상의 클라이언트에게 동시접속을 허용, 서비스를 제공한다.
멀티 프로세스 기반 서버
멀티플렉싱 기반 서버
멀티 쓰레딩 기반 서버
- 클라이언트의 수 만큼 쓰레드를 생성해 서비스를 제공한다.
프로세스, 프로세스 ID
프로세스
- 실행중인 프로그램과 이용중인 메모리 및 리소스
프로세스 ID
프로세스의 생성
#include <unistd.h>
pid_t fork(void);
성공시 프로세스ID, 실패시 -1을 반환한다.
- 호출한 프로세스가 복사되어, 각각의 프로세스로 작동하게 된다.
- 부모 프로세스는 자식 프로세스의 PID를 리턴받고, 자식 프로세스는 0을 리턴 받는다.
- 이를 통해 프로세스의 흐름을 구분한다.
- child와 parent 프로세스의 실행 순서는 정해진게 없다.
좀비 프로세스
- 실행이 완료되었으나 소멸되지 않은 프로세스
- 원래는 main 함수 리턴시 소멸되어야 한다.
- 즉, 프로세스가 사용한 리소스가 메모리에 여전히 존재한다.
생성 원인
- 자식 프로세스가 종료하면서 반환하는 상태값이 부모 프로세스에게 전달되지 않았다.
생성 확인
wait함수를 사용해 좀비 프로세스 소멸하기
- wait 함수의 경우 자식 프로세스가 종료되지 않을시 blocking 상태에 놓인다.
- wait(&status) 함수를 통해 자식 프로세스의 실행 결과를 받는다.
- status는 int type
waitpid 함수를 사용하기
#include <sys/wait.h>
pid_t waitpid(pid_t pid, int* statloc, int options);
성공시 종료된 자식 프로세스 ID 혹은 0, 실패시 -1을 반환
- pid : 종료를 확인하고자 하는 자식 프로세스 ID, -1 전달시 임의의 자식 프로세스 종료를 기다림
- statloc : wait 함수의 status와 동일
- options : sys/wait.h 의 WNOHANG을 인자로 전달시, 종료된 자식 프로세스가 없어도 0을 반환하며 함수를 빠져나온다.
시그널 핸들링
시그널
- 특정 상황이 되었을때 운영체제가 프로세스에 해당 상황을 알리는 일종의 메시지
- 우리가 쓸것은 SIGCHLD
시그널 등록
- OS로부터 시그널을 받기 위해선 해당 상황에 대해서 등록 과정을 거쳐야 한다.
sigaction 함수
#include <signal.h>
int sigaction(int signo, const struct sigaction* act, struct sigaction* oldact);
성공시 0, 실패시 -1을 반환한다.
- signo : signal 함수와 마찬가리조 시그널의 정보를 인자로 전달
- act : 시그널 발생시 호출될 함수의 정보
- oldact : 이전에 등록되었던 시그널 핸들러의 함수 포인터
- sa_hanlder : 시그널 처리 함수, int를 패러미터로 받고 void를 리턴함.
- sa_mask : 마스킹
- sigemptyset(&act.sa_mask) 를 통해 0으로 만들수 있다.
- sa_flags : 플래그
시그널 핸들링과 좀비 프로세스 소멸
- waitpid 실행하고 WEXITSTATUS 통해 리턴 출력
멀티태스킹 기반 다중접속 서버
- 부모 프로세스가 accept를 통해 연결요청 수락
- 얻은 소켓 파일 디스크립터를 자식 프로세스를 생성해 넘겨줌
- 자식 프로세스가 전달받은 파일 디스크립터 기반으로 서비스 제공
- 서로에게 상관 없는 파일 디스크립터를 닫아준다.
- 자식 프로세스에게 서버 File descriptor
- 부모 프로세스에게 클라이언트 File descriptor
입출력 루틴 분할
- 소켓은 양방향 통신 가능, 클라이언트 단에서 입력과 출력을 담당하는 프로세스 각각 생성해 별도 진행 가능하다.