Posix C管道延迟

时间:2014-04-12 22:23:05

标签: c posix pipe dup2

我遇到了一个令人讨厌的问题:

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

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

我有另一个程序,让我们把它命名为Redirector,代码有​​点复杂:

#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 个答案:

答案 0 :(得分: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时关闭管道的读取端。但是,在这个程序中,这也无所谓。