2

我遇到了一个棘手的问题:

假设我有一个程序,我们把它命名为 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;
}

那里没有说明一些错误检查,这是为了使代码更简单。我仍然无法理解这件事:

当 Redirector 与 HelloProgram 一起使用以重定向其输出时,所有“Hello”文本仅在 3 * 10(== 迭代次数)== 30 秒后才会显示到控制台屏幕,

这他妈到底是什么?我想它会是某种并行的,所以我每 3 秒后在控制台上显示每个“Hello”字符串。

请帮帮我。

4

1 回答 1

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()。在这种情况下,它可能无关紧要,但一般来说,您不希望它保持打开状态。可以说,当读取 EOF 时,其中的代码parent_proc()应该关闭管道的读取端。但是,在这个程序中,这也无关紧要。

于 2014-04-12T22:44:31.500 回答