什么时候我可以期待“stdout”打印到控制台

时间:2013-07-15 15:30:17

标签: c linux

我知道这是因为缓冲了stdout但是我什么时候可以在下面的程序中期望输出stdout。如果我跑,我总是得到“stderr”作为输出。如果我添加'\ n'或fflush(标准输出),那么只有我得到两个语句。如果我不添加'\ n'或fflush(stdout),我没有得到“stdout”作为输出。如果我不添加'\ n'或fflush(stdout),我什么时候才能将所有缓冲的“stdout”作为输出。

#include <stdio.h>
#include <unistd.h>
int main()
{
      for(;;)
      {
              fprintf(stdout,"stdout");
              fprintf(stderr,"stderr");
              sleep(1);
      }
      return 0;
} 

3 个答案:

答案 0 :(得分:4)

实际上,新行或者齐声因为默认stdout在引用终端设备时是行缓冲的。

更确切地说:标准输入和标准输出是完全缓冲的,当且仅当它们不引用交互式设备时。标准错误永远不会完全缓冲。

关于线路缓冲,引自APUE

  

线路缓冲有两个警告。首先,标准I / O库用于收集每一行的缓冲区大小是固定的,因此如果我们在写入换行符之前填充此缓冲区,则可能发生I / O.其次,无论何时通过标准I / O库从(a)无缓冲流或(b)行缓冲流(需要从内核请求数据)请求输入,都刷新所有行缓冲输出流。 (b)中限定符的原因是所请求的数据可能已经存在   在缓冲区中,不需要从内核读取数据。显然,来自无缓冲流(项目(a))的任何输入都需要从内核获取数据。

要将其更改为无缓冲,请使用setvbuf

setvbuf(stdout, NULL, _IONBF, 0);

答案 1 :(得分:0)

发送到stderr的输出通常会立即打印。这是标准错误输出。当然,错误应该立即显示,因此任何存在的缓冲区都会立即刷新。

另一方面,stdout是缓冲的。打印出来的缓冲区因语言而异,但通常至少需要以下两种方法之一:/n或其他类型的换行符或.flush();。如果您不提供这些选项,那么通常您必须等待缓冲区填充。这可能需要花费任何时间,因为它几乎完全取决于缓冲区的大小。

按照惯例,处理流的方式是您根据需要将尽可能多的信息推送到它们中,然后调用.flush()。如果缓冲区恰好在此期间填满,那么数据将被发送到任何地方,缓冲区开始再次填满。

但是,这里填写了一个接收文本的缓冲区。与二进制信息相比,文本并没有真正占用大量空间(这是一个非常主观的陈述,应该松散地解释),因此填充缓冲区可能需要一段时间。

最佳做法是,在您将所有要打印的文本“送入”之后,手动清除流(stdout)。

答案 2 :(得分:0)

默认情况下,

fprintf 是行缓冲的。您可以通过调用 setvbuf 来改变行为。它允许您将其设置为“unbuffered”,“line buffered”或“full buffered”。