2009-06-10 4 views
9

무슨 뜻인지 설명 할 수있는 example입니다 :왜 파이프를 읽고 쓸 때 fds를 닫아야합니까? 여기

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

int main(void) 
{ 
     int  fd[2], nbytes; 
     pid_t childpid; 
     char string[] = "Hello, world!\n"; 
     char readbuffer[80]; 

     pipe(fd); 

     if((childpid = fork()) == -1) 
     { 
       perror("fork"); 
       exit(1); 
     } 

     if(childpid == 0) 
     { 
       /* Child process closes up input side of pipe */ 
       close(fd[0]); 

       /* Send "string" through the output side of pipe */ 
       write(fd[1], string, (strlen(string)+1)); 
      exit(0); 
    } 
    else 
    { 
      /* Parent process closes up output side of pipe */ 
      close(fd[1]); 

      /* Read in a string from the pipe */ 
      nbytes = read(fd[0], readbuffer, sizeof(readbuffer)); 
      printf("Received string: %s", readbuffer); 
    } 

    return(0); 

} 그러나

, 내 프로세스 중 하나가 다른 파이프를 읽을 필요가있는 동안 지속적으로 파이프에 기록 할 필요가있는 경우 무엇?

위 예제는 하나의 쓰기 및 하나의 읽기에 대해서만 작동하는 것처럼 보입니다.

+0

작업의 원 자성을 보장하기 위해 하나의 프로세스가 파이프를 사용하면 "파이프를 잠글"수 있습니다. 모든 프로세스가 파이프로 끝나면 그 파이프 중 하나가 닫힙니다. – Skurmedel

+0

그들은 프로그램 기간 동안 파이프로 끝나지 않을 것입니다. –

+1

확인. 그런 다음 마지막 마무리 프로세스가 종료됩니다. 하나의 파이프에 여러 개의 파이프를 열거 나 하나의 파이프에 대한 액세스를 동기화하십시오. – Skurmedel

답변

23

파이프는 단방향 스트림이며 각 끝의 파일 설명자가 있습니다. 데이터가 파이프를 통과 할 수 있도록 파이프 끝을 닫을 필요는 없습니다.

파이프가 프로세스 (즉 fork() 전에 생성 된 후 부모와 자식이 통신을 위해 사용하는 경우)은 쓰기 및 읽기를 각각 하나씩 가질 수 있습니다. 그런 다음 파이프의 원하지 않는 끝을 닫는 것이 좋습니다. 이것은

  • 이 파이프를 닫을 때 읽기 끝이 보이는지 확인하십시오. 예를 들어, 자녀가 쓰기 편이라면, 그것은 죽는다. 부모 쓰기 측이 닫히지 않은 경우, 부모는 파이프로부터 "eof"(길이가 0 인 read())를 얻지 않을 것입니다. 파이프는 쓰기 엔드가 열려 있기 때문입니다.
  • 쓰기 작업을 수행중인 프로세스와 파이프에서 읽기를 수행중인 프로세스를 분명히하십시오. 당신의 파이프 (동일한 프로세스 내에서) 스레드를에 걸쳐있는 경우

후 파이프의 원치 않는 끝을 닫지 마십시오. 이것은 파일 디스크립터가 프로세스에 의해 유지되고 하나의 스레드에 대해 닫히면 모든 스레드에 대해 닫히기 때문에 파이프가 사용할 수 없게되기 때문입니다.

하나의 프로세스가 파이프에 지속적으로 쓰고 다른 프로세스가 읽는 것을 멈추게하는 것은 없습니다. 이것이 문제라면, 우리에게 당신을 도울 수있는 더 자세한 정보를주십시오.

+0

나는 하나의 reader - parent와 하나의 writer - child 쓰레드만을 가지고있다 - –

+4

당신이 쓰레 디드 환경에 있다면, 파일 서술자는 다양한 쓰레드에 의해 공유된다. 따라서 이러한 상황에서는 완전히 끝날 때까지 파이프의 읽기/쓰기 끝을 닫지 마십시오. 그렇지 않으면 파이프가 닫힙니다. 이제는 파이프가 프로세스에 걸쳐있을 때 원하지 않는 끝을 닫습니다. 파이프가 프로세스 내에서 스레드에 걸쳐있을 때 원치 않는 끝을 닫지 않습니다. – Beano

11

포크 수행 후 모든 fds가 복제됩니다. 각 프로세스는 파이프의 양쪽 끝을 엽니 다. 한쪽 끝만 사용하려면 다른 쪽 끝을 닫아야합니다 (프로세스가 쓰는 경우 읽기 끝내기).

OS가 디스크립터를 닫지 않으면 열려있는 파일 테이블에 여분의 항목이 남아있게됩니다. 파이프의 쓰기 끝을 닫지 않으면 판독기가 EOF를받지 못합니다. 파이프에 데이터를 입력하는 방법. AFAIK (및 IIRC)에서는 다른 프로세스에서 읽기 fd를 닫지 않아도 문제가 없습니다. 즉, 파일이 아무 이유없이 열려있는 것 외에는 없습니다.

응용 프로그램을 종료하기 전에 모든 설명자를 닫는 것이 좋습니다 (즉, 너무 많이 영향을주는 것은 아닙니다). 즉, 각 응용 프로그램에서 읽기/쓰기 작업이 완료된 후에 파이프의 다른 끝을 닫는 것이 좋습니다 프로세스)

+0

약간의 설명, 나는 그렇지 않다. 프로세스하지만 스레드를 만들고 파이프 쓰기 끝을 쓰기 위해 쓰레드에 쓰십시오. –

+0

왜 포크를 작성합니까? 포크는 쓰레드를 만들지 않습니다. 자식 프로세스를 만듭니다. – qrdl

+0

그건 사실 예제입니다. 실제로 시작합니다. 프로세스와는 별도의 스레드. –

0

파이프가 양방향 채널을 제공하지 않으며 멀티 캐스팅되지 않습니다. 파이프는 단지 두 끝으로, 하나의 쓰기 엔드와 다중 읽기 엔드를 갖지 않습니다.

많은 독자가 필요하면 독자 프로세스가있는만큼 많은 파이프가 필요합니다.

+0

부모 한 명과 작가 - 자식 스레드 한 명만 있습니다. –

0

"위 예제는 하나의 쓰기 및 하나의 읽기에 대해서만 작동하는 것처럼 보입니다."

코드를 한 번 읽고 쓰면 코드가 종료되기 때문에 루프에 쓰기를 계속하고 연속성을 유지하기 위해 루프를 읽어야하기 때문에 FD가 닫히는 것과 관련이없는 것 같습니다. 다른 하나는 폐쇄 그래서 이전 응답에서 각 과정에 대한 한 쪽 끝을해야합니다.

내가 쿼리 권리를 이해하는데 도움이되기를 바랍니다.

0

에만 동기화를 위해, 내가 무엇을 생각

관련 문제