2014-12-09 7 views
0

파이프가 어떻게 작동하는지 이해하려고하는데 교과서에서이 코드를 읽을 때 혼란 스럽습니다. 우리가 그것을 중복 직후 왜 우리가 fd2[0]을 복제하는 라인파이프를 닫고 파이프를 복제하는 방법

dup(fd2[0]); close(fd2[0]); 

에서 닫습니다?

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

int main() { 
    struct timespec ts1, ts2; 
    pid_t newpid; 
    int fd1[2], fd2[2]; 
    char m0[] = "\nabout to fork....\n"; 
    char m1[] = "message from parent to child\n"; 
    char m2[] = "message from child to parent\n"; 
    char m3[] = "\ndone....\n"; 
    char rbuf1[256]; 
    char rbuf2[256]; 
    int cn1, cn2; 
    ts1.tv_sec=(time_t)1; 
    ts1.tv_nsec=(long)1; 
    ts2.tv_sec=(time_t)1; 
    ts2.tv_nsec=(long)1; 
    if ((pipe(fd1)==-1)) printf("error\n"); 
    if ((pipe(fd2)==-1)) printf("error\n"); 
    printf("fd1 %d %d fd2 %d %d\n", fd1[0], fd1[1], fd2[0], fd2[1]); 

    if ((newpid=fork()) ==-1) { 
    printf("failed to fork\n\n"); 
    return 0; 
    } 

    if (newpid > 0) { // parent *************** 
    close(fd1[1]); close(fd2[0]); // closing 4 and 5 
    dup(fd2[1]); close(fd2[1]); // taking 4 in place of 6 
    write(4, m1, sizeof(m1)); // parent_to_child messg 
    usleep(10000); 
    cn1=read(3, rbuf1, 256); 
    write(1, rbuf1, cn1); 
    } else { // child *************** 
    close(fd1[0]); close(fd2[1]); // closing 3 and 6 
    dup(fd2[0]); close(fd2[0]); // taking 3 in place of 5 
    write(4, m2, sizeof(m2)); // child_to_parent messg 
    usleep(10000); 
    cn2=read(3, rbuf2, 256); 
    write(1, rbuf2, cn2); 
    } 
    write(2, m3, sizeof(m3)); 
    return 0; 
} 
+3

코드는 귀하의 질문과 관련이없는 것 같습니다. 어디서나 "dup"을 볼 수는 없습니다. – Sentry

+0

죄송합니다, 내 질문에 코드의 두 번째 절반을 추가하는 것을 잊지 – Learning

+0

코드를 포맷하십시오. –

답변

1

당신은 dup()oldfd에 대한 새 파일 기술자를 반환합니다, dup()

int dup(int oldfd); 

dup() uses the lowest-numbered unused descriptor for the new descriptor. 

명확하게 말한다 이쪽 man page의에서, 그러나, 우리에게 코드를 보여주지 않았다 . 새 fd을 얻으려면 dup()의 반환 값을 할당해야합니다. 새로운 fd을 얻으면 이전 fd을 닫고 새로 반환 된 설명자를 사용하여 파일에 액세스 할 수 있습니다.

일반적으로 널리 사용되는 접근 방법은 잘 알려진 파일 설명자를 닫고 그 후에 dup()을 호출하여 최근 닫힌 fd을 새 fd으로 지정합니다. [예 : STDIN_FILENO]

+0

그 말은 내가 close (fd)를 호출 할 때마다 이전 fd를 닫고 새로운 fd를 닫지 않는다는 의미입니까? – Learning

+0

@Learning yes,'close()'에 오래된'fd'를 제공했다면 말입니다. 리턴 값은 새로운'fd'를 줄 것이다. –

0

일반적인 순서는 dup 호출 전에 다른 close 호를 가지고, 또는 dup 결과를 할당하고 사용하기위한 것이다.

첫 번째 변형은 dup이 후 가장 낮은 가능한 기술자를 선택 때문이 작동

close(STDIN_FILENO); // Close the current standard input descriptor 
dup(pipefds[0]);  // Duplicate the pipe read-end, which will become our new standard input 
close(pipefds[0);  // Close the old pipe descriptor, to save descriptor resources 

을 할 수있는 새로운 STDIN_FILENO로 파이프 읽을 끝을 사용하는 예를 들어, 가장 일반적입니다 첫 번째 close 전화는 STDIN_FILENNO (설명자 0)입니다.

그리고 dup은 같은 "파일"을 참조하는 두 가지 설명이있을 것이다 dup를 호출 후 그래서 가, 기술자를 복제, 그것은 같은 souds 정확히 수행, 그 중 수 자유롭게 가까운 하나.

the dup(2) manual page을 읽어 보시기 바랍니다.