본문 바로가기

프로그래밍/ 리눅스

I/O - poll

 

poll() 도 select()와 비슷하다.

가장 큰 차이점은 감시할 fd를 지정하는법이 다르다.

select에서는 감시할 fd를 지정 할 수 있는 3개의 set을 제공 했지만..

poll 에서는 감시할 이벤트를 설정 할 수 있도록 fd 목록을 제공한다.

 

 

#include "poll.h"
int poll( struct pollfd fds[], nfds_t nfds, int timeout );
// 준비된 fd 수를 리턴하고 타임 아웃은 0, 에러는 -1을 리턴한다.

struct pollfd {
    int fd;
    short events; // 요청한 이벤트 비트 마스크
    short revents; // 리턴된 이벤트 비트 마스크
};

// events를 초기화 하여 fd에 감시할 이벤트를 지정하고
// revents 를 통해 감시하던 fd에서 어떤 이벤트가 발생 했는지 알 수 있다.

 

 

 

 비트

 설명 

 POLLIN

 높은 우선순위 데이터 외의 데이터를 읽을 수 있다.
 POLLRDNORM  POLLIN과 같다
 POLLRDBAND  우선순위 데이터를 읽을 수 있다
 POLLPRI

 높은 우선순위 데이터를 읽을 수 있다

 POLLRDHUP  상대편 소켓 셧다운
 POLLOUT  일반 데이터를 기록 할 수 있다
 POLLWRNORM  POLLOUT와 같다
 POLLWRBAND  우선순위 데이터를 기록 할 수 있다.

 POLLMSG

  리눅스에서는 사용 안함.

 POLLERR  에러 발생
 POLLHUP  장애 발생 (hangup)
 POLLVAL  fd가 열리지 않았다.

 

 

하늘색 필드는 입력과 연관된 이벤트이다. EVENTS의 입력 란에서 사용 할 수 있고 REVENTS에서 리턴 하는 값이다.

주황색 필드는 출력과 연관된 이벤트다. EVENTS의 입력 란에서 사용 할 수 있고 REVENTS에서 리턴 하는 값이다.

연두색 필드는 리눅스에서 사용 안함

회색 필드는 REVENTS 필드에서만 사용하는 FD의 추가 정보이다.

fd 에서 특정 이벤트에 관심이 없으면 events를 0으로 설정 한다. 그리고 revents는 항상 0을 리턴하도록 fd 필드값을 음수로 설정해 events 필드값을 무시하도록 설정 할 수 있다.

 

 

#include "poll.h"
#include "time.h"

int numPipes = 10; // pipe 갯수를 10개로 셋팅..
int (*pfds)[2] = calloc( numPipes, sizeof( int[2] ) ); // 사용할 pipe 배열 할당
if ( NULL == pfds ) return;

// pipe 생성 ------------------------------------------------------
for ( int i = 0; i < numPipes; ++i ) {
    if ( -1 == pipe( pfds[ i ] ) )
        return; // 생성 에러..
}

// pipe 기록 ------------------------------------------------------
int numWrites = 3; // pipe에 기록할 데이터 갯수
for ( int i = 0; i < numWrites; ++i ) {
    int randPipe = random() % numPipes; // 전체 pipe 갯수에 나눠서 기록..
    if ( -1 == write( pfds[ randPipe ][1], "a", 1 ) )
        return; // 쓰기 에러
}

// pipe event ------------------------------------------------------
struct pollfd* pollFd;
for ( int i = 0; i < numPipes; ++i ) {
    // 모든 pipe에 POLLIN 이벤트 감시.. 
    pollFd[ i ].fd = pfds[ i ][ 0 ];
    pollFd[ j ].events = POLLIN;
}

// pollfd 전달..
int ready = poll( pollFd, numPipes - 1 );

// poll 로 가져온 revents에 POLLIN 으로 설정되어 읽을 수 있는 fd 출력..
for ( int i = 0; i < numPipes; ++i ) {
    if ( pollFd[ i ].revents & POLLIN )
        printf("Readable : %d %3d\n", i, pollFd[ i ].fd );
}

 

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

ssh 접속하기  (2) 2017.04.28
I/O - epoll  (0) 2013.03.25
I/O - select  (0) 2013.03.24
I/O 모델 종류..  (0) 2013.03.24
프로세스  (0) 2013.03.24