고급 I/O 모델 : poll() 함수

System Program/I/O 2014. 3. 12. 20:44

1. poll() 시스템 함수

 

select()와 비슷한 작업을 수행한다. select() 함수가 BSD로부터 기원한다면 poll() 함수는 시스템 V로부터

기원한다. 두 함수간에 차이점으로는 파일디스크립터를 관리하는 방식면에서 서로 다르다.

 

#include <poll.h>

 

int poll(struct pollfd fds[], nfds_t nfds, int timeout);

 

준비된 파일 디스크립터 수를 리턴한다.

타임 아웃일 경우 '0'을, 에러가 발생하면 '-1'을 리턴한다. 

 

pollfd 구조체는 아래와 같다. nfds는 pollfd 배열의 갯수를 의미한다.

 

struct pollfd {

int fd;                                                        /* 파일 디스크립터 */

short events;                                             /* 확인하기를 원하는 이벤트에 대한 비트마스크 */

short revents;                                            /* 리턴된 이벤트 마스크 */

}; 

 

1.1. timeout 값

 

 값

설명 

 -1

 pollfd 구조체에 포함된 파일 디스크립터 중 하나가 준비되거나 이벤트를 수신할 때까지

 블록한다. (블록의 정도는 파일디스크립터의 종류에 따라 다르다)

 0

 블록하지 않고 파일디스크립터가 준비 상태인지만을 확인한다.  

 0 보다 큰값

 최대 설정된 타임아웃 기간만큼 블록한다.  

 

 1.2. 리턴값

 

 값

설명 

 -1

 에러가 발생 

 0

 파일 디스크립터가 준비되기 전에 타임아웃된 경우

 양수

 준비된 파일 디스크립터의 갯수

 

2. events/revents에 대한 비트 마스크 값

 

 비트

events 

revents 

설명 

 POLLIN

 O

 O

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

 POLLRDNORM

 O

 O

 상동 (리눅스는 POLLIN과 동일하게 동작)

 POLLRDBAND

 O

 O

 우선순위 데이터를 읽을 수 있다. (리눅스 사용 안함)

 POLLPRI

 O

 O

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

 POLLRDHUP

 O

 O

 상대편 소켓 셧다운

 POLLOUT

 O

 O

 일반 데이터를 기록할 수 있다.

 POLLWRNORM

 O

 O

 상동 (리눅스는 POLLOUT과 동일하게 동작)

 POLLWRBAND

 O

 O

 우선순위 데이터를 기록할 수 있다.

 POLLERR

 X

 O

 에러가 발생했다.

 POLLHUP

 X

 O

 장애가 발생했다.

 POLLNVAL

 X

 O

 파일 디스크립터가 열리지 않는다.

 POLLMSG

 X

 X

 리눅스에서는 사용하지 않음.

 

3. 파일 디스크립터의 준비 상태

 

select()와 poll() 함수는 모든 파일 디스크립터 종류에서 블록되지는 않는다. 파일 디스크립터의 종류마다

블록의 동작이 다르다. 예로 일반 파일에 대한 파일 디스크립터는 블록하지 않고 바로 리턴한다.

이 예제가 select() 함수편의 예제에서 select() 함수의 리턴값을 찍어보면 알 수 있다.

따라서 I/O 멀티플렉싱 기법을 사용 시에는 파일 디스크립터의 종류에 대한 블록 동작에 대해서 잘 살펴봐야 한다.

 

4. 예제

 

select() 함수 예제 편에서 디스크 파일 디스크립터를 대상으로 했다면, 여기서는 표준 입력을 블록 대상으로 하였다.

select() 함수 편에서 retval값을 보면 실제 블록되지 않는다. 항상 준비된 상태가 된다.

파일 디스크립터 종류에 따른 블록되는 현상 차이를 보기위해서 poll() 예제에서는 표준 입력을 대상으로 예제를

작성하였다. 두 예제 간의 차이점을 보는 것도 도움이 될 것이다.  

 

/*
* main.c -- C Test App.
*
* Copyright (C) 2012-2013, 2013 heesoon.kim <chipmaker.tistory.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; version 2 of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <limits.h>
#include <errno.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <time.h>
#include <sys/types.h>
#include <poll.h>

#define MAX_BUFFER_LEN 256

int main(int argc, char *argv[])
{
	int retval, m_read, m_write;
	int fd;
	struct pollfd pollfds[1];
	char buffer[MAX_BUFFER_LEN];
	
	if((fd = open("./temp.txt", O_RDWR)) == -1)
	{
		perror("open : ");
		exit(EXIT_FAILURE);
	}

	pollfds[0].fd = STDIN_FILENO;
	pollfds[0].events = POLLIN;
	
	while(1)
	{
		memset(buffer, 0x00, MAX_BUFFER_LEN);
		retval = poll(pollfds, 1, -1);
		if(retval == -1)
		{
			perror("poll : ");
			exit(EXIT_FAILURE);			
		}
		
		printf("retval = %d \n", retval);
		
		if(pollfds[0].revents & POLLIN)
		{
			m_read = read(STDIN_FILENO, buffer, MAX_BUFFER_LEN);
			printf("[read] m_read = %d \n", m_read);
			
			m_write = write(fd, buffer, m_read);
			printf("[write] m_write = %d \n", m_write);
		}
		
		usleep(1000);
	}

	close(fd);
	exit(EXIT_SUCCESS);
}

 

'System Program > I/O' 카테고리의 다른 글

고급 I/O 모델 : epoll() 함수  (0) 2014.03.13
고급 I/O 모델 : select() 시스템 호출  (0) 2014.03.01
access() 함수  (0) 2014.02.26
stat() 관련 함수  (0) 2014.02.26
fcntl() 함수  (0) 2014.02.21
: