缓冲区同步机制
为什么需要缓冲区同步
c++是基于c语言的扩展语言,本质上它继承了c语言许多特性,同时也继承了C语言特性,在c语言中stdio为输入输出缓冲区,stdin是输入缓冲区,stdout是输出缓冲区,C++不与C语言使用同一个缓冲区,这就出现了一个问题,当使用printf、cout输出语句时因为它俩不使用同一个缓冲区就会出现输出语句不同步的情况,例如(在没有缓冲区同步的机制情况下):
printf("test 1");
cout << "test 2" << endl;
输出:
test2test1
可以看到test2早于test1输出了,这是因为c语言的机制,c语言缓冲区只有在遇到\n、程序结束、缓冲区满时才会刷新缓冲区。
缓冲区同步在C++中实现原理
C++为了解决在使用C/C++混合编程时带来的输出语句不同步的情况,在使用cout这一类输出语句时会去读取stdout指针指向输出缓冲区里的内容,如果stdout里有内容,那么强制调用fflush来刷新C语言的缓冲区,这样有效解决了缓冲区不同步的情况,但是也带来了不好的问题,那就是每次调用cout打印语句时它都会去检查缓冲区,如果我们不使用C/C++混合编程时它就极大的降低了我们程序的运行效率。
不使用缓冲区同步
如果在使用纯C++编程时我们是不会出现上述的情况的,所以C++提供了一个API:sync_with_stdio来为我们解决这个问题,通过这个API可以让C++不在去检查输出缓冲区,这个API一般用在纯C++编程或不使用stdio的情况下,因为使用它可能会导致缓冲区混乱的情况,它的函数原型如下:
void sync_with_stdio(bool sync = true);
当sync为true时开启缓冲区同步
当sync为false时关闭缓冲区同步
注意事项
在一些项目中一般有自己的LOG模块,在一些大型项目中一般是多人开发,很难控制工程师们不去使用printf、cout这类C/C++混合输出语句,但是你的LOG模块又是纯C++开发的,你在LOG模块里为了提升效率使用了sync_with_stdio关闭缓冲区同步,那么一定要写好醒目的注释或其它提示方法来告知工程师不要使用C语言的输出语句。
缓冲区同步仅针对stdout有效
对于stdin,它们对应的是输入操作,输入的内容会被存储到内存中,而不是直接输出到屏幕。因此,cin等C++语句与C语言的stdin之间不会有干扰或同步问题。