멀티플렉싱이란?
여러명이서 통신할때 하나의 채널만 가지고 통신하는 방식을 말한다.
멀티쓰레드, 멀티 프로세스가 여러 채널을 만들어 통신한다면 멀티플렉싱은 하나의 프로세스, 스레드를 가지고 여러 명의 통신을 연결시킨다.
멀티플렉싱 모델은 먼저 소켓 리스트들을 등록하고, 등록된 소켓 리스트들 중에 send나 recv와 같은 I/O 작업이 수행 가능한 준비 상태의 소켓들을 알려주는 API를 제공한다.
여러명이 접속할 수 있는 서버를 만들기 위해 여러 IO모델들이 사용된다. 오늘은 대표적인 멀티플렉싱 방식의 IO 모델인 select에 대해 알아보자
select 동작 과정
서버는 여러 클라이언트의 접속을 받는다. 그 후 각 클라이언트의 이벤트(데이터 수신여부, 데이터 송신가능 여부, 오류 수신 여부 등)의 이벤트가 들어옴에 따라 해당 클라이언트에게 적절한 응답을 해줘야 한다.
select I/O 모델은 select 함수가 핵심이 되는 모델이다.
select 함수를 통해 소켓 함수 호출이 성공할 시점을 미리 알 수 있다.
select 함수가 소켓이 send, recv를 할 수 있는지 체크해준다.
select 모델은 blocking socket, non-blocking socket 각각이 가진 문제점을 해결해준다.
기존 socket 프로그래밍의 경우 다음과 같은 문제 상황이 나타날 수 있다.
1. 수신 버퍼에 데이터가 없는데, read를 하는 경우
2. 송신 버퍼가 꽉 찼는데, write 하는 경우
이 경우 select 함수를 사용하면 문제가 해결된다.
blocking socket의 경우에는 조건이 만족되지 않아서 블로킹되는 상황을 예방할 수 있고,
non-blocking socket의 경우에는 조건이 만족되지 않아서 불필요하게 반복 체크해야 하는 상황을 방지할 수 있다.
장점
가장 큰 장점은 멀티스레드, 멀티프로세스와 다르게 교착상태, 레이스 컨디션을 피하고 하나의 스레드에서 안정적으로 처리 가능하다는 점이다.
단점
1. FD_SETSIZE가 64로 작다
fd_set에 최대 64개의 소켓을 설정할 수 있으며, 따라서 큰 set이 필요하다면 set을 여러개 만들어줘야 한다.
2. 매번 소켓 set을 초기화 해야한다
따라서 단순하지만 최대 성능을 보인다고는 할 수 없다.
IOCP란?
Input/Ouptput Completion Port의 약자다. 입력과 출력의 완료를 담당할 포트를 지정해서 처리하겠다는 의미다. 입력과 출력의 완료시점에서의 통지는 overlapped(중첩 입출력)에서 처리가 되므로, 이 기술은 윈도의 중첩 입출력 기술을 확장시킨 것으로 볼 수 있다.
간단히 말하면 윈도우에서 제공하는 비동기 IO 라이브러리로 생각하면 될것이다
구동방식
- 적당한 수의 워커 쓰레드를 생성한다. (보통 (코어수 * 2) + 1)
- 소켓 생성
- 클라이언트 접속 시도시 accept 함수 호출
- 연결 완료시 Complete Port 할당
- WSARecv함수를 호출해 입출력 디바이스에서 입출력이 완료되면 completion queue에 등록하고 워커 쓰레드에 할당한다.
순으로 구동되는 방식이다. 일반적으로 보이는 쓰레드 풀 방식에 비해 쓰레드에 작업을 할당하는 방식을 원도우에서 자동으로 해주는 점에서 편하다고 할수 있다.