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 |