본문 바로가기
Linux System/Linux

[func] poll

by rewyear 2020. 4. 7.

poll

select와 마찬가지로 다중 입출력을 구현하기 위한 방법으로 사용되며, 동시에 여러 개의 클라이언트를 다루는 서버를 제작하기 위한 방법으로 흔히 사용된다.

int poll(struct pollfd *ufds, unsigned int nfds, int timeout);

fd의 이벤트를 기다리다가 이벤트가 발생하면 poll에서 block이 해제되고, 다음 루틴에서 어떤 fd에 이벤트가 발생했는지 검사하는 방식

 

 

pollfd

첫 번째 인자인 pollfd 구조체

struct pollfd
{
	int fd;         // 대기할 이벤트의 fd
	short events;   // 어떤 이벤트를 기다릴지 지정
	short revents;  // 돌려받을 이벤트
};

서버가 기다릴 이벤트의 fd를 세팅하고, 어떤 이벤트를 기다릴 것인지 events를 통해 지정하게 된다.

 

위와 같이 설정한 후 poll은 해당 fd에서 지정한 event가 발생하는지 검사하게 되고, 해당 이벤트가 발생하면 revents에 특정 값을 대입하고 리턴하는 역할을 한다.

 

여기서 revents는 events에 대해서 어떻게 반응하는지 알려줄수 있는 값이다.

 

 

events 종류

세팅할 수 있는 events의 종류

#define POLLIN      0x0001  // 읽을 데이타가 있다.
#define POLLPRI     0x0002  // 긴급한 읽을 데이타가 있다.
#define POLLOUT     0x0004  // 쓰기가 봉쇄(block)가 아니다. 
#define POLLERR     0x0008  // 에러발생
#define POLLHUP     0x0010  // 연결이 끊겼음
#define POLLNVAL    0x0020  // 파일지시자가 열리지 않은것같은
                                // Invalid request (잘못된 요청)

 

nfds는 pollfd의 배열의 크기 즉 서버가 이벤트를 대기하는 fd의 개수이다.

 

timeout의 경우 msec단위로 대기할 시간을 설정한다.

  • 값을 지정하지 않을 경우 이벤트가 발생하기 전까지 무한히 대기
  • 0일 경우 이벤트를 기다리지 않고 바로 0리턴
  • 0보다 큰 양의 정수일 경우, 해당 시간만큼 wait 

return

  • 에러일 경우 -1 반환
  • timeout일 경우 0 반환
  • 성공 시 이벤트가 발생한 fd개수 

 

예제

// pseudo code
// 해당 예제는 리눅스 전용 poll인 ppoll을 사용하였다.

struct pollfd fds[DEV_MAX];

struct timespec timeout_ts;

timeout_ts.tv_sec = time / kTimeSecond;
timeout_ts.tv_nsec = (time % kTimeSecond) * kTimeNanosecondsPerMicrosecond;

for(int i=0; i<DEV_MAX; i++)
{
	fds[i].fd = _m_fd[i];
	fds[i].events = POLLIN;
	fds[i].revents = 0;
}

int ret = ppoll(fds, DEV_MAX, &timeout_ts, nullptr);
DBG("first fd revent : %d, second fd revent : %d", fds[0].revents, fds[1].revents);
	

	
300x250

'Linux System > Linux' 카테고리의 다른 글

[func] mmap() / munmap() - memory 맵핑  (0) 2021.07.23
[cmd] install 명령어  (0) 2020.08.05
[func] fcntl  (0) 2020.04.07
Patch file 만들기(git diff 활용)  (0) 2020.03.04
[cmd] md5sum  (0) 2020.03.04