我遇到了一个令人讨厌的问题:
假设我有一个程序,让我们将其命名为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'字符串。
请帮帮我。
答案 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时关闭管道的读取端。但是,在这个程序中,这也无所谓。