Skip to content

Study : CPP : select

sma96 edited this page Apr 1, 2022 · 6 revisions

select()

멀티 플렉싱

  • 여러 입출력 대상을 하나로 묶어 관리하는 방식이다.
  • 하나의 서버가 여러 클라이언트를 처리할 수 있다.
  • 멀티 프로세스, 쓰레드가 아닌 싱글 프로세스, 쓰레드에서 동작한다.
  • 여러 이벤트 처리 대상이 있을 때 그 대상들을 이벤트가 생길 때까지 대기하고 있다가 이벤트 발생 시 처리하는 것이 아닌, 대상들을 하나씩 돌아가며 이벤트 발생 여부를 체크하여 발생된다면 처리하는 방식이다.

어떤 소켓 fdread, write, exeption이 발생했는지 확인하는 함수

FD_SET으로 인해 1로 set 되어 있는 파일 디스크립터를 순회하면서 변화가 있는 파일 디스크립터 개수를 반환한다.

파일에 변화가 있다면 그대로 1로 두고, 없다면 0으로 set

#include <sys/select.h>

int select(int nfds, ft_set *restrict readfds, fd_set *restrict writefds, 
							fd_set *restrict errorfds, struct timeval *restrict timeout);

    리턴 값
    -1          오류발생
    0           타임아웃
    0보다 큰 수   변화발생 파일 디스크립터 수
  • nfds 인자 : 검사 대상이 되는 파일 디스크립터의 수
  • readfds 인자 : 읽기 준비 상태인지 검사할 fd_set
  • writefds 인자: 쓰기 준비 상태인지 검사할 fd_set
  • errorfds 인자: 예외 상황인지 검사할 fd_set
  • timeout 인자 : null 이면 변화가 있을 때까지 계속 대기(블럭킹), 아니면 일정 시간 대기후 시간 초과 리턴됨.

select 함수에서 대기라는 의미가 한 fd에서만 계속 대기하는 것이 아니다.

fd_set에서 변화가 발생한 fd를 찾을 때까지 fd_set 배열을 계속 순회하는 것을 의미한다.

  • fd_set 구조체

    • fd(소켓)를 그룹 짓게 하기 위해서 사용된다.
    • 비트 단위 배열이다.
    • 구조체 안에 변수 fds_bits[]fd 를 저장할 수 있다. (총 1024개의 fd만 검사할 수 있다.)

    FD_ZERO

    fd_set rfds;
    FD_ZERO(&rfds);

    위와 같이 fd_set으로 선언된 변수를 초기화할 때 사용한다. 모든 비트 값을 0으로 만들어 준다.

    FD_SET

    int fd_socket = socket(AF_INET, SOCK_STREAM, 0);
    fd_set rfds;
    FD_ZERO(&rfds);
    FD_SET(fd_socket, &rfds);

    fd_socket 값을 fd_set으로 선언된 rfds 변수에 추가할 때 사용한다.

    FD_CLR

    FD_CLR(fd, fd_set)

    FD_SET과 반대의 기능을 수행한다.

    자신이 추가했던 fd 값에 해당 하는 비트를 0으로 만들어 준다.

    FD_ISSET

    FD_ISSET(fd, ft_set)

    fd_set으로 선언된 변수에 특정 fd 값이 설정되어 있는지 확인할 때 사용한다. 설정이 되어 있다면 0이 아닌 값을, 없다면 0을 반환한다.

    man page

    https://wariua.github.io/man-pages-ko/select%282%29/