2014-04-12 4 views
2

나는 불쾌한 문제에 직면 어떤 코드가 약간 복잡합니다 :하여 Posix C 배관 지연

#define READ_END 0 
#define WRITE_END 1 

int pipe_fd[2]; 
void child_proc(const char* prg_name) { 
close(pipe_fd[READ_END]); 

dup2(pipe_fd[WRITE_END], STDOUT_FILENO)); 
execl("/bin/sh", "sh", "-c", prg_name, NULL); 
//error 
exit(1); 
} 

void parent_proc() { 
close(pipe_fd[WRITE_END]); 
char buffer[256]; 
while (read(pipe_fd[READ_END], buffer, sizeof(buffer)) > 0) { 
    printf(buffer); 
} 

wait(NULL); 
} 

int main(int argc, const char* argv[]) { 
pipe(pipe_fd); 
pid_t chpid = fork(); 
if (chpid != 0) { 
    parent_proc(); 
} else { 
    child_proc(argv[1]); 
} 

return 0; 
} 

거기에 몇 가지 오류 검사가 없으므로 코드를 더 간단하게 만들 수 있습니다.

리디렉터가 HelloProgram과 함께 사용되어 출력을 리다이렉트 할 때 모든 'Hello'텍스트는 콘솔 화면에 3 * 10 (== 반복 횟수) = = 30 초,

대체 무엇입니까? 나는 그것이 평행의 일종이라고 생각했기 때문에 매 3 초가 지난 후에 콘솔에 각 'Hello'문자열이 표시됩니다.

도와주세요.

+1

출력을 표시하려면 줄 바꿈으로 문자열을 완성하십시오. 그렇지 않으면 스트림을 fflush() 또는 fclose() 할 때까지 보류 상태가되거나, 개행 문자를 출력합니다. 'dup2()'를 사용하여 표준 출력을 작성한 후에도 파이프 파일 설명자를 닫아야합니다. –

답변

3

HelloProgram의 출력을 적시에 표시하려면 각 printf() 끝에 줄 바꿈을 포함 시키거나 fflush()을 사용하여 강제로 출력해야합니다. HelloProgram의 출력이 터미널로가는 경우 줄 바꿈으로 충분합니다. 그것이 파이프로가는 경우 fflush()이 필요합니다. 따라서

:

void print_bullshit(void) 
{ 
    int i; 
    for (i = 0; i < 10; ++i) 
    { 
     printf("hello!\n"); 
     fflush(stdout); 
     sleep(3); 
    } 
    printf("bye!\n"); 
    fflush(stdout); 
} 

이 가능한시기 적절한 표준 출력에 자료를 보내드립니다. 다른 코드에서

, 당신은이 :

void child_proc(const char* prg_name) 
{ 
    close(pipe_fd[READ_END]); 
    dup2(pipe_fd[WRITE_END], STDOUT_FILENO)); 
    execl("/bin/sh", "sh", "-c", prg_name, NULL); 
    //error 
    exit(1); 
} 

당신은 일반적으로 필요가 추가하려면 dup2() 호출 후

close(pipe_fd[WRITE_END]); 

합니다. 이 경우 중요하지 않을 수 있지만 일반적으로 공개하지 않으려는 경우입니다. 대체로 parent_proc()의 코드는 EOF를 읽었을 때 파이프의 읽기 끝을 닫아야합니다. 그러나이 프로그램에서는 그 중 하나도 중요하지 않습니다.