2011-05-02 7 views
11

폴링 기능을 사용하여 일부 파이프의 끝을보아야하는 프로그램을 작성하려고합니다. poll이> 0을 반환 할 때마다 for 루프가 모든 파이프를 검사하도록하고 파이프가 다른 끝에있는 프로 시저에서 닫히면 POLLHUP 또는 POLLIN | pollfd 구조체의 revents 필드에있는 POLLHUP.폴 C 함수를 사용하여 Linux에서 명명 된 파이프를 보는 방법은 무엇입니까?

내 질문은 : 파이프 하나가 실제로 닫히고 POLLHUP을 반환하면 다음 루프에서 어떤 일이 발생합니까? POLLHUP을 반복적으로 반환 할 것인가? 아니면 폴링 함수가 첫 번째 POLLHUP 후에 그것을 무시할 것인가?

+5

는 소리를. –

+0

나는 시도했지만 무언가가 잘못되어 pollhup이 너무 많은 시간을 예상보다 많이 반환하므로 내 코드에 무엇이 잘못 될 수 있는지 궁금해서 질문을 던졌습니다. – nikos

+2

@nikos : 설문 조사에 답장을 보내고 싶을 수도 있습니다. 그 fd에서 이벤트에 더 관심이있는 경우 (또는 연결이 절반 닫힌 경우 일부 이벤트 만) –

답변

1

최소한의 예를

소스. 사용법 : 다른 쉘에

sudo mknod poll0.tmp p 
sudo mknod poll1.tmp p 
sudo chmod 666 poll*.tmp 
./poll.out 

:

printf a > poll0.tmp 
printf b > poll1.tmp 

출력 : 대한 poll 대기 루프없이 읽는 방법

loop 
POLLIN i=0 n=1 buf=a 
loop 
POLLHUP i=0 
loop 
POLLIN i=1 n=1 buf=b 
POLLHUP i=1 
loop 

그래서 알 수 있습니다.

쿨러 예 :

(while true; do date; sleep 1; done) > poll0.tmp & 
(while true; do date; sleep 2; done) > poll1.tmp & 

0는 1 초마다 작성하고, 도착 poll() 서로 실속없이, 동시에 두개의 입력을 처리하는 방법을 도시 1 2 초마다.

출처 :

#define _XOPEN_SOURCE 700 
#include <fcntl.h> /* creat, O_CREAT */ 
#include <poll.h> /* poll */ 
#include <stdio.h> /* printf, puts, snprintf */ 
#include <stdlib.h> /* EXIT_FAILURE, EXIT_SUCCESS */ 
#include <unistd.h> /* read */ 

int main(void) { 
    enum { N = 2 }; 
    char buf[1024], path[1024]; 
    int fd, i, n; 
    short revents; 
    struct pollfd pfds[N]; 

    for (i = 0; i < N; ++i) { 
     snprintf(path, sizeof(path), "poll%d.tmp", i); 
     /* O_NONBLOCK is required or else the open blocks 
     * until the other side of the pipe opens. */ 
     fd = open(path, O_RDONLY | O_NONBLOCK); 
     if (fd == -1) { 
      perror("open"); 
      exit(EXIT_FAILURE); 
     } 
     pfds[i].fd = fd; 
     /* Only events in this mask will be listened to. 
     * However, there are also some events that are unmaskable, 
     * notably POLLHUP when pipe closes! */ 
     pfds[i].events = POLLIN; 
    } 
    while (1) { 
     puts("loop"); 
     i = poll(pfds, N, -1); 
     if (i == -1) { 
      perror("poll"); 
      exit(EXIT_FAILURE); 
     } 
     for (i = 0; i < N; ++i) { 
      revents = pfds[i].revents; 
      if (revents & POLLIN) { 
       n = read(pfds[i].fd, buf, sizeof(buf)); 
       printf("POLLIN i=%d n=%d buf=%.*s\n", i, n, n, buf); 
      } 
      if (revents & POLLHUP) { 
       printf("POLLHUP i=%d\n", i); 

       /* This happens when the other side closed. 
       * This event is only cleared when we close the reader. */ 

       /* poll won't set POLLHUP anymore once all fds are closed. 
       * Any futher polls on this will give the POLLNVAL event instead. */ 
       close(pfds[i].fd); 

       /* negative fds are ignored. So if we negate an FD, 
       * we can both turn if off for a while, and turn it on 
       * later on by re-nagating it. */ 
       pfds[i].fd *= -1; 
      } 
     } 
    } 
} 

컴파일과 :

gcc -o poll.out -std=c99 poll.c 

우분투 14.04에서 테스트.

GitHub upstream. 하나 개의 파이프가 실제로 폐쇄 나에게 POLLHUP을 반환받을 않는 경우

는 무엇 다음 루프에서 발생합니다

은 원래의 질문에 대답하려면? POLLHUP을 반복적으로 반환 할 것인가? 아니면 폴링 함수가 첫 번째 POLLHUP 후에 그것을 무시할 것인가?

는 줄을 제거 :

close(pfds[i].fd); 
pfds[i].fd *= -1; 

당신은 POLLHUP을 통해 영원히 루프 것을 볼 수 있습니다.단지

제거 :

close(pfds[i].fd); 

하고 폐쇄 FD 사용하려고 당신이 대신 POLLNVAL를 얻을 :이 테스트하여 알아내는 매우 간단 것 같은 Linux socket handling revents POLLERR POLLHUP POLLNVAL

관련 문제