본문 바로가기

프로그래밍/ 리눅스

I/O - select

 

select() 호출은 1개 이상의 fd가 준비될때까지 블록 한다.

#include "sys/time.h"
#include "sys/select.h"

int select( int nfds, fd_set* readfds, fd_set* writefds, fd_set* exceptfds, struct timeval* timeout );
// 준비된 fd수를 리턴한다. 타임 아웃이 발생하면 0을 리턴, 에러일 경우 -1을 리턴 한다.
// fd_set* readfds : 입력이 가능한지를 확인할 파일 디스크립터 집합
// fd_set* writefds : 출력이 가능한지를 확인할 파일 디스크립터 집합
// fd_set* exceptfds : 예외조건이 발생했는지를 확인할 파일 디스크립터 집합

// select()의 블록 동작을 제어. 0을 설정하면 블록하지 않고,
// 대기 상태인지만 확인 후 즉시 리턴, 값을 설정하면 설정된 값만큼 기다림.
struct timeval {
    time_t tv_sec; // 초
    suseconds_t tv_usec; // 마이크로초 long int
}

void FD_ZERO( fd_set* fdset ); // fdset을 초기화
void FD_SET( int fd, fd_set* fdset ); // fd 를 fdset이 가리키는 집합에 추가
void FD_ISSET( int fd, fd_set* fdset ); // fd가 fdset에 속해 있으면 1을 리턴, 아니면 0을 리턴

// fd집합의 최대 크기는 FD_SETSIZE(1024) 로 정의 되어 있다.

// 아래는 select() 예제.. 참 쉽죠~ + _+ㅋ
// 실행은 안해봐서 될지 모르겠다 -_-;;

    fd_set read, write;
    int nfds = 0; // fd 갯수

    // fd_set 초기화
    FD_ZERO( &read );
    FD_ZERO( &write );

    int fd = 0;
    for ( int i = 0; i < 10; ++i )
    {
        char buf[10] = { 0,};
        scanf("%s", buf );

        if ( fd >= FD_SETSIZE ) return; // fd가 최대 갯수를 넘으면 안된다.

        // nfds는 fd보다 1 크게 설정한다.
        if ( fd >= nfds )
            nfds = fd + 1;

        // buf 입력값이 r이면 read
        if ( strchr( buf, 'r' ) != NULL )
            FD_SET( fd, &read );

        // buf 입력값이 w이면 write
        if ( strchr( buf, 'w' ) != NULL )
            FD_SET( fd, &write );

        ++fd;
    }

    struct timeval pto;
    pto.tv_sec = 0;
    pto.tv_usec = 0;
    
    int ready = select( nfds, &read, &write, NULL, &pto );
    if ( ready == -1 ) return; // 에러 발생..
    
    // 준비된 fd 갯수를 리턴한다.
    printf( "ready fd count %d\n", ready );

    for ( fd = 0; fd < nfds; ++fd )
        printf("%s", FD_ISSET( fd, &write ) ? "w" : "..");


 

 

 

'프로그래밍 > 리눅스' 카테고리의 다른 글

I/O - epoll  (0) 2013.03.25
I/O - poll  (0) 2013.03.25
I/O 모델 종류..  (0) 2013.03.24
프로세스  (0) 2013.03.24
파일디스크립터..  (0) 2013.03.24