C: stdout hangs linux pipes
我用C语言编写了一个简单的I/O回显程序,用一个更大的实际程序测试一个问题。在这里,Linux FD重定向不起作用。
回音程序(aka a.out)是:
1 2 3 4 5 6 7 8 9 10
| #include <stdio.h>
int main (int argc , char **argv ) {
char buff [10];
while (1) {
if (fgets(buff , 10, stdin ) == NULL ) break;
printf("PRINT: %s
", buff );
}
} |
在bash中,我的运行方式是:
1 2 3 4 5 6
| $ mkfifo IN OUT
$ # this is a method to keep the pipes IN and OUT opened over time
$ while :; do read; echo Read: $REPLY >&2; sleep 1; done <OUT >IN &
$ a.out >OUT <IN &
$ echo xyz >IN |
而且没有产生输出:bash while循环无法从OUT中读取。
让我们将这个a.out与cat进行比较,后者按预期工作:
1 2 3 4 5 6
| $ mkfifo IN OUT
$ while :; do read; echo Read: $REPLY >&2; sleep 1; done <OUT >IN &
$ cat >OUT <IN &
$ echo xyz >IN
Read: xyz |
最后一行在控制台上打印到stderr。cat的输出不同于A.Out的输出,它能够穿过OUT到达bash while循环,然后在控制台上打印。A.out出了什么问题?
- 我一直使用Linux管道(在bash中)和多个源代码。数据是随机复用的。对于一个管道,甚至可以有多个目的地,但在这里,行为是不可预测的。
- 其实,没关系,我说的话毫无意义!
- 如果我没有错,在将stdout重定向到管道之后,IO流将不会被缓存,而是被完全缓存。您也可以使用setbuf将其更改为线路缓冲
在printf(...)后加fflush(stdout)。
- 我添加了fflush(stdout),但它仍然和以前的a.out完全一样。(请原谅我的编辑)
- 对于添加了fflush(stdout)的我来说是有效的(或者通过简单地压倒缓冲区,即seq 1 1000>in)
- 哇,fflush()实际上解决了这个问题。这是我的错,因为我太忙了,注意力不集中。有了它,我还修复了更大的,真正的程序!