SELECT(2)

이름
select, FD_CLR, FD_ISSET, FD_SET, FD_ZERO - 동기적 I/O 다중화

사용법
#include <sys/time.h>
#include <sys/types.h>
#include <unistd.h>

int select(int n, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout);

FD_CLR(int fd, fd_set *set);
FD_ISSET(int fd, fd_set *set);
FD_SET(int fd, fd_set *set);
FD_ZERO(fd_set *set);

설명
select 는 상태가 변경되는 파일 기술자들의 숫자를 기다린다.

세개의 독립적인 파일 기술자 집합들을 검사한다. readfds 에 리스트된 것들은 문자들을 읽어들일수 있는가가 검사되며(더 정확히는, 읽기가 봉쇄되지 않았는지를 검사하기 위해서이다 - 특별히, 파일 기술자 또한 end-of-file 일수도 있다.), writefds 에 있는 것들은 쓰기가 봉쇄되지 않았는가가 검사되며 exceptfds 에 있는 것들은 예외가 있는지가 검사된다. 종료시, 이 집합들은 파일 기술자들이 실제로 변경된 상태가 무엇인지 가리키도록 수정된다.

네개의 매크로가 이 집합들을 제어하기 위해 사용된다. FD_ZERO 는 집합을 소거한다. FD_SET 와 FD_CLR 는 집합에서 주어진 기술자를 더하거나 뺀다. FD_ISSET 는 기술자가 집합의 일부분인지 아닌지를 검사한다.: 이것은 select 가 반환된후 유용하다.

n 은 세개의 집합중 가장 높은 파일기술자에다가 1을 더한다.

timeout 은 select 가 반환하기 전에 경과해야 하는 시간의 상위 제한 값이다. 0으로 지정되면 select 는 즉시 반환된다. 만일 timeout 이 NULL이면(timeout이 없을경우), select 는 무한히 봉쇄될수 있다.

반환값
성공시, select 는 파일 기술자 집합에 포함된 기술자들의 숫자를 반환하며, 어떠한 일이 일어나기 전에 타임아웃이 발생하면 0을 반환한다. 에러시, -1이 반환되며, errno 는 적당한 값으로 설정된다.; 집합들과 timeout 은 정의가 안되며, 그래서 에러후 이것들의 내용에 의지할수 없다.

에러

EBADF
    유효하지 않은 파일 기술자가 집합중 하나에 들어 있다.

EINTR
    비-블럭된 신호가 잡혔다.

EINVAL
    n 이 음수이다.

ENOMEM
    select 가 내부 테이블들을 위한 메모리를 할당할수 없다.

주의
몇몇 코드들은 정확성을 가지고 잠복시키기 위해 꽤 호환되는 방법으로써 세개의 집합을 비우고, n 은 0, 그리고 timeout 은 null이 아니게 설정하여 select 를 호출한다.

리눅스에서, timeout 은 잠복되지 않은 시간의 양을 반영하기 위해 수정된다; 대부분의 다른 수행들은 이렇게 되지 않는다. 이것은 timeout 을 읽은 리눅스 코드들이 다른 OS로 포팅되거나 코드들이 초기화를 다시 하지 않고 반복문에서 다중 selects 를 위해 timeval 구조체를 다시 사용하여 리눅스로 포팅할때 문제들을 야기한다. select 에서 반환된후 정의되지 않은 timeout 을 고려해야 한다.

예제
#include <stdio.h>
#include <sys/time.h>
#include <sys/types.h>
#include <unistd.h>
int
main(void)
{
    fd_set rfds;
    struct timeval tv;
    int retval;
    /* 입력된때를 알아보기 위해 stdin (fd 0)을 검사한다. */
    FD_ZERO(&rfds);
    FD_SET(0, &rfds);
    /* 5초를 기다린다. */
    tv.tv_sec = 5;
    tv.tv_usec = 0;
    retval = select(1, &rfds, NULL, NULL, &tv);
    /* 지금 tv 값에 의존하지 마라. */
    if (retval)
        printf("Data is available now.\n");
        /* FD_ISSET(0, &rfds) 는 true이다. */
    else
        printf("No data within five seconds.\n");
    exit(0);
}

호환
4.4BSD ( select 함수는 4.2BSD에서 처음 나타났다.). 일반적으로 BSD 소켓 층(System V 변종들을 포함하여)의 복사판들을 지원하는 non-BSD계열과 호환된다. 그러나, System V 변종들은 전형적으로 종료전에 timeout 변수를 설정하지만, BSD 변종들은 그렇게 하지 않는다는것을 주의해라.

관련 항목
accept(2), connect(2), poll(2), read(2), recv(2), send(2), write(2)

역자
정강훈 <skyeyes@soback.kornet.net>, 2000년 7월 1일