【1.LINUX系统下】
一般而言,大家都知道printf是带有行缓冲的函数,printf把打印的消息先输出到行缓冲区,在以下几种情况下:1.程序结束时调用exit(0)/return;2.遇到回车\n,3.调用fflush函数;4.缓冲区满。会自动刷新缓冲区,缓冲区的内容显示到标准输出上。

比如在LINUX系统下,执行如下程序:

  1. #include <stdio.h>
  2. int main(void)
  3. {
  4.     printf("hello");    
  5.     while(1);
  6.     return 0;
  7. }
使用GCC编译后执行,发现shell中并没有输出hello,这是因为LINUX系统下,printf把“hello”输出到缓冲区,而此时没有发生缓冲区刷新的4种情况,因此shell中并不会看到hello。但是如果使用printf("hello\n");或者在printf后使用fflush(stdout);那么执行时在shell中就会看到hello输出。

【2.WINDOWS系统下】
同样这段程序,如果在Windows下编译运行(使用VC++6.0),会发现控制台中马上看到hello的输出。分析原因发现,Windows下stdout没有提供缓冲(不知道这个原因是否确切)。比如执行如下程序:

  1. #include <stdio.h>
  2. int main(void)
  3. {
  4.     printf("hello\n");
  5.     printf("buf size is %d\n",stdout->_bufsiz);
  6.     while(1);
  7.     return 0;
  8. }
可以看到stdout的缓冲区大小为0,这也就意味着,stdout是没有缓冲区的,因此printf输出到stdout,不存在缓冲,这个和LINUX系统中对printf处理的机制是不一样的。

在Windows下,可以使用setbuf函数(https://msdn.microsoft.com/en-us/library/86cebhfs.aspx)来设置缓冲区的方式和大小。

  1. #include <stdio.h>
  2. char buf[512];
  3. int main(void)
  4. {
  5.     setvbuf(stdout, buf, _IOLBF, 512);
  6.     printf("hello");    
  7.     while(1);
  8.     return 0;
  9. }
使用setbuf函数,把stdout设置为行缓冲,大小为512字节。在VC++6.0中运行该程序,发现不会在控制台中输出hello,如果把缓冲区设置为2个字节大小:setvbuf(stdout, buf, _IOLBF, 2);此时程序的输出为hell,he输出到缓冲区,缓冲区满,刷新缓冲区,控制台看到he,ll输出到缓冲区,缓冲区满,再次刷新,控制台看到ll,o输出到缓冲区,此时缓冲区未满,因此看不到o在控制台输出。

使用如下程序,查看缓冲区的大小,输出结果为512字节
  1. #include <stdio.h>
  2. char buf[512];
  3. int main(void)
  4. {
  5.     setvbuf(stdout, buf, _IOLBF, 512);
  6.     printf("hello\n");
  7.     printf("%d\n",stdout->_bufsiz);
  8.     fflush(stdout);
  9.     while(1);
  10.     return 0;
  11. }

此外,在Windows设置缓冲区的情况下,printf中使用回车符\n是不会刷新缓冲区的。对上述程序,把fflush函数注释掉,在VC++6.0中重新执行,控制台中看不到输出。





10-03 15:37