2014-04-12 41 views
2

我遇到了一道难题:Posix的ç管道延迟

假设我有一个计划,让我们将其命名为HelloProgram其代码非常简单:

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

而且我还有一个程序,让我们将其命名为重定向,它的代码是有点复杂:

#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重定向它的输出,所有的“你好”文本后,才给予控制台屏幕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); 
} 

你需要,一般情况下补充:

close(pipe_fd[WRITE_END]); 
dup2()电话后

。在这种情况下,这可能并不重要,但总的来说,你不希望它敞开。可以说,parent_proc()中的代码在读取EOF时应关闭管道的读取端。但是,在这个程序中,这也不重要。