在C语言中,完全缓冲,行缓冲和非缓冲是什么意思?

hun*_*eas 4 c linux

我碰到一行,cat命令的输出已完全缓冲。这是什么意思?

Joh*_*ode 6

在线C11标准 7.21.3 / 3:

当流没有缓冲时,字符应尽快从源或目标出现。否则,字符可能会作为块被累积并传输到主机环境或从主机环境传输。当流被完全缓冲时,打算在填充缓冲区时将字符作为块与主机环境进行传输。当流被行缓冲时,当遇到换行符时,字符打算作为块与主机环境进行传输。此外,当填充缓冲区,在无缓冲流上请求输入或在需要从主机环境传输字符的行缓冲流上请求输入时,打算将字符作为块传输到主机环境。 。对这些特性的支持是实现定义的,并且可能会受到setbufsetvbuf功能的影响。

7.21.3 / 7:

在程序启动时,预定义了三个文本流,无需显式打开它们- 标准输入(用于读取常规输入),标准输出(用于写入常规输出)和标准错误(用于写入诊断输出)。最初打开时,标准错误流未完全缓冲;当且仅当可以确定该流不引用交互式设备时,标准输入流和标准输出流才被完全缓冲。


ike*_*ami 5

[为了简洁和易于复制,我在示例中使用 Perl,但我所说明的概念并非 Perl 特有的。C 以同样的方式工作。]

缓冲决定了写入文件句柄的内容刷新(发送)到操作系统的频率。比较以下两个命令的行为:

# With buffering (default)
perl -e'$|=0; print "a"; sleep(2); print "b\n";'

# Without buffering
perl -e'$|=1; print "a"; sleep(2); print "b\n";'
Run Code Online (Sandbox Code Playgroud)

通常,缓冲区仅在变满时才刷新。当遇到换行符时,行缓冲输出也会被刷新。比较:

perl -e'print "a"; sleep(2); print "b\n";'

perl -e'print "a\n"; sleep(2); print "b\n";'
Run Code Online (Sandbox Code Playgroud)

大多数程序都使用块缓冲。然而,当标准输出连接到终端时,它们通常会切换到行缓冲。比较:

# Perl's STDOUT is line-buffered when connected to a terminal.
perl -e'print "a\n"; sleep(2); print "b\n";'

# Perl's STDOUT is fully buffered when connected to a pipe.
perl -e'print "a\n"; sleep(2); print "b\n";' | cat

# unbuffer uses pseudo-ttys to fool a program into thinking it's connected to a terminal.
unbuffer perl -e'print "a\n"; sleep(2); print "b\n";' | cat
Run Code Online (Sandbox Code Playgroud)