'programming'에 해당되는 글 387건

  1. 2013.04.04 select / poll 시스템 콜 이해하기

반응형

 

http://knight76.tistory.com/entry/select-poll-시스템-콜-이해하기

 

 

select / poll 시스템 콜 이해하기


점점 까먹어진다. 틈틈히 복습하자..



1. select function 좋은 예제


5초동안 표준입력으로부터 입력값을 받는다. 5초 이내로 글자를 받으면 (해당 fd에 대한 값이 변경) 입력받은 문자를 그대로 출력

소스
#include <stdio.h>
#include <sys/time.h>
#include <sys/types.h>
#include <unistd.h>

#define TIMEOUT 5
#define BUF_LEN 1024

int main(void) {

struct timeval tv;
fd_set readfds;
int ret;

FD_ZERO(&readfds);
FD_SET(STDIN_FILENO, &readfds);

tv.tv_sec = TIMEOUT;
tv.tv_usec = 0;

// nfds is the highest-numbered file descriptor in any of the three sets, plus 1.

ret = select (STDIN_FILENO + 1, &readfds, NULL, NULL, &tv);
if (ret == -1) {
perror("select");
return 1;
} else if (!ret) {
printf ("%d senconds elapsed. \n", TIMEOUT);
return 0;
}

if (FD_ISSET(STDIN_FILENO, &readfds)) {
char buf[BUF_LEN + 1];
int len;

len = read(STDIN_FILENO, buf, BUF_LEN);
if (len == -1) {
perror("read");
return 1;
}

if (len) {
buf[len] = '\0';
printf("read : %s \n", buf);
}

return 0;
}

fprintf(stderr, "This should not happen!\n");
return 1;

}

$ gcc select-demo.c
$ ./a.out
5 senconds elapsed.
$ ./a.out
123
read : 123


2. man select 내용

/* According to POSIX.1-2001 */
#include <sys/select.h>

/* According to earlier standards */
#include <sys/time.h>
#include <sys/types.h>
#include <unistd.h>

int select(int nfds, fd_set *readfds, fd_set *writefds,
fd_set *exceptfds, struct timeval *timeout);

void FD_CLR(int fd, fd_set *set);
int FD_ISSET(int fd, fd_set *set);
void FD_SET(int fd, fd_set *set);
void FD_ZERO(fd_set *set);


#include <sys/select.h>

int pselect(int nfds, fd_set *readfds, fd_set *writefds,
fd_set *exceptfds, const struct timespec *timeout,
const sigset_t *sigmask);

pselect 라는 것이 있는데. 차이점이 있다.
1. 시간과 관련된 struct이 다르다. select : timeval, pselect : timespec (초와 나노초)
2. 시그널 관련 sigset_t가 있다. 시그널과 관련된 mask를 파라미터로 사용한다. select 함수는 signal 파라미터를 사용하지 않는다.
(pselect를 사용하는 예제를 거의 못본 것 같다. 나는 아직까지는 select만 사용하는 어플만 본 것 같다.)


pselect 예제는 sigprocmask 함수를 사용한 예제와 비슷하다.
ready = pselect(nfds, &readfds, &writefds, &exceptfds,
timeout, &sigmask);


sigset_t origmask;
sigprocmask(SIG_SETMASK, &sigmask, &origmask);
ready = select(nfds, &readfds, &writefds, &exceptfds, timeout);
sigprocmask(SIG_SETMASK, &origmask, NULL);


3. poll 좋은 예제

#include <stdio.h>
#include <unistd.h>
#include <sys/poll.h>

#define TIMEOUT 5

int main(void) {
struct pollfd fds[2];
int ret;

fds[0].fd = STDIN_FILENO;
fds[0].events = POLLIN;

fds[1].fd = STDOUT_FILENO;
fds[1].events = POLLOUT;

ret = poll(fds, 2, TIMEOUT * 1000);
if (ret == -1) {
perror("poll");
return -1;
}

if (!ret) {
printf("%d seconds elapsed. \n", TIMEOUT);
return 0;
}

if (fds[0].revents & POLLIN) {
printf ("stdin is readable.\n");
}

if (fds[1].revents & POLLOUT) {
printf ("stdout is writable.\n");
}

return 0;
}

결과
$ gcc poll-demo.c
$ ./a.out
stdout is writable.

$ touch xx.txt
$ ./a.out < xx.txt
stdin is readable.
stdout is writable.


4. man poll

#include <poll.h>

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

#define _GNU_SOURCE
#include <poll.h>

int ppoll(struct pollfd *fds, nfds_t nfds,
const struct timespec *timeout, const sigset_t *sigmask);


struct pollfd {
int fd; /* file descriptor */
short events; /* requested events */
short revents; /* returned events */
};

5. select 와 poll 비교

- poll 은 가장 높은 fd에 +1을 할 필요가 없다.
- poll은 fd가 클 경우 좋다. select는 모든 fd의 비트를 검사한다. (select는 for loop에서 set 된 정보를 찾음)
-> 그렇다고 select가 안좋다고 말할 수 없다. 이벤트가 자주발생하고 연속적인 시스템에서는 select를 사용 (apache http)
poll은 어느 정도 분산되어 있거나 크기 제한이 없는 여러개의 array 형태로 넘겨서 사용할 때 유용하다.
그리고, 필요한 것만 비교할 경우가 효과적이다.
- select는 fd set을 초기화를 해야 하지만, poll은 입력과 결과를 분리할 수 있다.
- select는 사이즈 제한이 있다.
- select가 이식성이 좋음. 어떤 시스템은 poll을 쓰지 않기도 함
- select의 timeout이 poll의 timeout보다 안정적임


6. 레벨트리거와 엣지트리거

select와 poll 은 레벨트리거

레벨 트리거 : 파일에 데이터가 있는지 여부에 대한 판단, 완전히 다 읽을때까지 계속 이벤트를 발생한다. 즉 '동안'에 집중
에지 트러거 : 파일이 특정 데이터를 저장하는 '특정시점'에만 발생

좋은 설명은 다음 블로그에서 잘 해놨다.
http://no1rogue.blog.me/30091246644
- 에지 트리거 : 인터럽트가 발생하여 레벨이 상승하거나 하강할 때.
- 레벨 트리거 : 인터럽트가 발생하여 그 레벨이 인가될 때.


출처
- http://no1rogue.blog.me/30091246644
- 리눅스 시스템 프로그래밍, 한빛미디어
- http://kldp.org/node/35279

반응형
Posted by 공간사랑
,