2012-09-20 3 views
0

그래서, 나는 그들 사이의 메시지를 전달하기 위해 파이프로 연결된 프로세스 링을 생성 할 내 운영 시스템 클래스에 대한 할당을 가지고 있습니다. 내 요구에 맞게 (또는 적어도 이해) 찾고있는 몇 가지 예제 코드를 발견했습니다. 예 코드 (약간 수정)입니다 :dup2가 printf를 차단 하나 fprintf를 차단하지 않습니까?

/* Program 4.1 */ 
#include <stdio.h> 
#include <stdlib.h> 
#include <unistd.h> 
#include <string.h> 
#include <errno.h> 

/* Sample C program for generating a unidirectional ring of processes.Invoke this program 
with a command-line arg ument indicating the number of processes on the ring. Communication 
is done via pipes that connect the standard output of a process to the standard input of 
its successor on the ring. After the ring is created, each process identifies itself with 
its process ID and the process ID of its parent. Each process then exits. */ 

void main(int argc, char *argv[ ]) 
{ 
int master_pid = getpid(); 
printf("master pid: %i\n", master_pid); 

int i;    /* number of this process (starting with 1) */ 
int childpid;  /* indicates process should spawn another  */ 
int nprocs;  /* total number of processes in ring   */ 
int fd[2];   /* file descriptors returned by pipe   */ 
int error;   /* return value from dup2 call    */ 
/* check command line for a valid number of processes to generate */ 
if ((argc != 2) || ((nprocs = atoi (argv[1])) <= 0)) { 
    fprintf (stderr, "Usage: %s nprocs\n", argv[0]); 
    exit(1); 
} 
/* connect std input to std output via a pipe */ 
if (pipe (fd) == -1) { 
    perror("Could not create pipe"); 
    exit(1); 
} 
printf("%s\n", "test"); 
//this section is blocking printf()? 
if ((dup2(fd[0], STDIN_FILENO) == -1) || 
    (dup2(fd[1], STDOUT_FILENO) == -1)) { 
    perror("Could not dup pipes"); 
    exit(1); 
} 
printf("%s\n", "test"); 

if ((close(fd[0]) == -1) || (close(fd[1]) == -1)) { 
    perror("Could not close extra descriptors"); 
    exit(1); 
} 
/* create the remaining processes with their connecting pipes */ 
for (i = 1; i < nprocs; i++) { 
    if (pipe (fd) == -1) { 
     fprintf(stderr,"Could not create pipe %d: %s\n", 
       i, strerror(errno)); 
     exit(1); 
    } 
    if ((childpid = fork()) == -1) { 
     fprintf(stderr, "Could not create child %d: %s\n", 
       i, strerror(errno)); 
     exit(1); 
    } 
    if (childpid > 0)  /* for parent process, reassign stdout */ 
     error = dup2(fd[1], STDOUT_FILENO); 
    else 
     error = dup2(fd[0], STDIN_FILENO); 
    if (error == -1) { 
     fprintf(stderr, "Could not dup pipes for iteration %d: %s\n", 
       i, strerror(errno)); 
     exit(1); 
    } 
    if ((close(fd[0]) == -1) || (close(fd[1]) == -1)) { 
     fprintf(stderr, "Could not close extra descriptors %d: %s\n", 
       i, strerror(errno)); 
     exit(1); 
    } 
    if (childpid) 
     break; 
} 

/* say hello to the world */ 
fprintf(stderr,"This is process %d with ID %d and parent id %d\n", 
     i, (int)getpid(), (int)getppid()); 
wait(1); 
exit (0); 
}  /* end of main program here */ 

출력한다 :

master pid: 30593 
test 
This is process 1 with ID 30593 and parent id 30286 
This is process 2 with ID 30594 and parent id 30593 

제가 수득

[1] 그래서

내가 궁금 ARGV 2- 이유 것입니다 dup2 섹션은 printf()가 실행되는 것을 막는가? 심지어 내가 뭔가를 인쇄 할 수 없다면, 나는 심지어 정확하게 메시지를 전달할 수 있을지 모르겠다. 또한, 왜 fprintf()가 이미 작동하지만, 내가 거기에 놓았을 것이라고 생각하지 않습니까?

편집 : 경로 0에 데이터를 전송하지 않습니다 ...

답변

1

printf은 파일 설명자 1 (또는 이와 동등한 STDOUT_FILENO) 인 stdout에 인쇄합니다. dup2(3)은 현재 stdout을 닫는 부작용이있는 현재 stdout 맨 위에 파이프의 파일 설명자를 복제하고 있습니다. 따라서 printf을 호출 한 후 해당 dup2을 호출하면 방금 만든 파이프에 실제로 데이터가 인쇄되고 터미널 출력으로 이동하지 않습니다. 이 프로그램 기간 동안 변경되지 않습니다하지 표준 출력, 표준 에러로 출력하고, 열려진 파일 기술자 (2 또는 동등 STDERR_FILENO) 때문에

fprintf(stderr, ...)는 여전히 작동, 그래서 그것은 터미널을 인쇄하고 있습니다.

+0

와우, 예, 완전히이 코드를 너무 오래 꼼짝 않고 바라 보았습니다. – Drake

0

의 printf()를 난 내 교수/TA이 걸릴 것이다, 그러나 현재와 마감 사이에 도시에서의 theyre 모두와 연결할 수있을 것입니다, 그것은 stdout을 사용하여 버퍼 된 데이터를 보냅니다. dup2로 경로 0을 방해하면 그 과정에서 stdout을 방해하고있는 것으로 보입니다.

dup2의 설명서 페이지에서 : dup2() makes newfd be the copy of oldfd, closing newfd first if necessary. 따라서 dup2(fd[0], STDIN_FILENO)으로 전화하면 stdout을 위반하게됩니다.

당신은 fprintf()가 작동하지만 printf()가 fprintf()에 어떤 경로를 사용하고 있습니까? stderr을 사용하는 경우, 그 경로로 아무 것도하지 않았으므로 계속 작동 할 것입니다.

관련 문제