select의 대체함수
select 기반의 멀티플랙싱 서버는 다음과 같은 특징이 있다.
- select 호출 시마다 매번 운영체제에 fd에 관한 정보를 전달.
- 반복문을 통한 파일 디스크립터 각각에 대한 접근
c
// 1번
cpy_reads = reads;
...
// 2번
for (int i = 0; i < fd_max + 1; i++)
{
if (FD_ISSET(i, &cpy_reads))
{
if (i == serv_sock) ...
무조건 대체함수?
- 그러나 이러한 대체함수가 항상 만능은 아니다.
- epoll, kqueue와 같은 함수는 운영체제에 따라서 사용에 제약이 있다.
- 또한 서버의 접속자 수가 많지 않을 경우에도 불필요하다.
epoll
주로 리눅스 계열에서 쓰는 i/o 멀티플랙싱 전용 함수들
- 반복문에서 상태변화의 확인을 위한 부분이 필요없다.
select함수에 대응하는epoll_wait함수 호출시, 정보를 매번 전달할 필요가 없다.
epoll_create
c
#include <sys/epoll.h>
int epoll_create(int size);
- size : fd 저장소의 크기.
- 반환값 : fd 저장소를 가리키는 파일 디스크립터.
- 이 fd 저장소를 epoll 인스턴스라고 한다.
epoll_ctl
소켓 fd를 등록하는 함수.
c
#include <sys/epoll.h>
int epoll_ctl(int epfd, int op, int fd, struct epoll_event *event);
epfd: epoll 인스턴스의 파일 디스크립터op: 관찰대상의 추가, 삭제 또는 변경여부 지정- 여기에 들어가는 상수들이 존재한다.
fd: 등록할 소켓 fdevent: fd를 저장할 곳.
epoll_wait
c
#include <sys/epoll.h>
int epoll_wait(int epfd, struct epoll_event *events,
int maxevents, int timeout);
- epfd : epoll 인스턴스의 fd
- events : 이벤트를 담는 배열
- maxevents : events에 등록 가능한 최대 이벤트 갯수
- timeout : 대기시간 (밀리세컨 = 0.001초 단위)
events에서 이벤트가 벌어진 fd를 찾아 그 수를 반환.
몇 개의 fd에서 이벤트가 벌어졌는지 확인할 수 있다.
epoll_event는 다음과 같이 생겼다.
c
struct epoll_event
{
__uint32_t events; // 관찰하고자 하는 event
epoll_data_t data; // 이벤트와 관련된 추가 데이터
}
typedef union epoll_data
{
void *ptr;
int fd;
__uint32_t u32;
__uint64_t u64;
} epoll_data_t;
따라서 모든 소켓 fd를 검사하지 않고, 이벤트가 발생한 일부만 검사하면 된다.
레벨 트리거와 엣지 트리거
트리거 : 일반적으로 특정 이벤트가 발생했을 때 특정 동작이나 처리가 시작되도록 하는 메커니즘.
레벨 트리거와 소켓
입력버퍼에 데이터가 있으면 계속해서 이벤트가 등록되는 것
엣지 트리거와 소켓
입력버퍼에 데이터가 있으면 1번만 이벤트가 등록되는 것