Linux缓冲机制
Linux缓冲简介
Linux提供了无缓冲和缓冲的IO操作函数。
原生的IO例程read
,write
,lseek
,close
是无缓冲的。
而标准的IO库fread
,fwrite
,fseek
,fclose
则是带缓冲的。
无缓冲是指由开发人员自己传递读写的数据和大小,如果设置传递的数据太小,例如每次读写一个char,那么1M的文件将可能产生一百万次的系统调用,这样效率非常慢。所以程序员要设置好buffer的值,已达到最好的效率,通常将数据大小设置为文件系统的块大小,一般为4K。(虽然用户层不缓冲,但是内核存在缓冲
)
而标准库函数是带缓冲的,实际上是对IO例程的封装,通过在用户层缓冲来减少系统调用的次数。
Linux缓冲机制
全缓冲
:全缓冲指的是系统在填满标准IO缓冲区之后才进行实际的IO操作;注意,对于驻留在磁盘上的文件来说通常是由标准IO库实施全缓冲。行缓冲
:在这种情况下,标准IO在输入和输出中遇到换行符时执行IO操作;注意,当流涉及终端的时候,通常使用的是行缓冲。无缓冲
:无缓冲指的是标准IO库不对字符进行缓冲存储;注意,标准出错流stderr通常是无缓冲的。
缓冲验证程序1
|
|
- 使用
./buffer1
运行该程序的时候,输出结果是:
|
|
行缓冲是当遇到换行符或者缓冲满了的时候才进行实际的IO操作,程序中用了换行符,那么在创建子进程前父进程输出一次缓冲输出并清空缓冲,此时子进程不会再输出。
若改为printf("before fork");
则输出两次。
- 使用
./buffer1 > a.txt
运行该程序的时候,文件中的输出结果是:
|
|
对于磁盘中的文件通常是实施全缓冲,所以子进程创建以后还会输出缓冲区的内容一次。
缓冲验证程序2
|
|
程序输出结果是什么?
很多人以为是6个-
,但答案是8个-
。
解析
:
程序进行两次循环。
第一次父进程fork
一个子进程,这时候父进程和子进程都输出一个-
,共2个。
第二次父进程再次fork
一个子进程,此时父进程继续输出一个-
,而由于之前没有清空缓冲,故这次由父进程创建的子进程会输出两个-
。共3个。
对于第一次创建的子进程也是同理。共3个。
所以一共输出的-
为8个。
如果将程序对应语句改为printf("-\n");
则输出6个。