linux下I/O缓冲
2015-08-16 17:04
531 查看
缓冲区
作用:在实际编程中,I/O速度取决于显示器、键盘、硬盘等I/O设备的性能,而这些设备比起CPU和内存是比较慢的。因此系统采用缓冲区的方式来减少I/O的读写,以便提高系统性能。
I/O的缓冲区的种类:1、无缓冲;2、行缓冲;3、全缓冲。
一、行缓冲:
看一个例子:
[cpp] view
plaincopy
#include <stdio.h>
int main(void)
{
printf("123\n456");
while(1){}
return 0;
}
结果:
[cpp] view
plaincopy
123
这段代码只输出了“123\n”而没有输出“456”。原因是标准I/O:stdin,stdout是行缓冲。
行缓冲的特性是:C标准输出先写到行缓冲区里,当遇到下列四种情况才一次性把行缓冲区的数据写到I/O设备里去:
1、遇到\n字符;
2、行缓冲区(linux默认大小为1024字节)被填满后。
3、调用冲洗缓冲区的函数:fflush等。
4、进程返回、调用exit退出、文件流关闭等。
上例中printf的作用是把"123\n456"依次写入缓冲区,由于中途遇到\n,因此立即会把缓冲区里的所有数据——"123\n"写入I/O设备(此处是屏幕),接着的是把“456”写到缓冲区里。“456”之后没有“\n”、缓冲区又没有满、程序死循环在while(1)里没有结束,因此“456”将永远不会输出到I/O设备里。
属于行缓冲的I/O设备通常是需要交互的I/O:键盘(默认的stdin),屏幕(默认的stdout)等。
二、全缓冲
还是上面的代码(假设生成的执行程序名为“a.ex”,并且目录下有个“b.txt”的文本),如果这样启动:
[cpp] view
plaincopy
$ a.ex > b.txt
那么程序将不会输出任何字符到b.txt中。
因为对于文件(文件是在硬盘上的),硬盘I/O属于全缓冲。
全缓冲的特性是:C标准输出先写到全缓冲区里,当遇到下列三种情况才一次性把全缓冲区的数据写到I/O设备里去:
1、全缓冲区被填满后。
2、调用冲洗缓冲区的函数:fflush等。
3、进程返回、调用exit退出、文件流关闭等。
上例中启动a.ex程序时,用重定向符号“>”将stdout重定向到b.txt里。由于b.txt是文件,属于硬盘I/O,所以并满足全缓冲的写入条件。
属于全缓冲的I/O设备有:硬盘等。
三、无缓冲
[cpp] view
plaincopy
#include <stdio.h>
#include <unistd.h>
int main(void)
{
write(STDOUT_FILENO,"123\n456",7);
while(1){}
return 0;
}
结果是:
[cpp] view
plaincopy
123
456
没错,无缓冲会直接将字符串写入I/O设备里去。
write写文件或者屏幕等设备都是无缓冲的;stderr无论重定向到哪里都是无缓冲的。
四、最后补充一些注意:
[cpp] view
plaincopy
#include <unistd.h>
#include <stdio.h>
int main(void)
{
printf("123\n456");
_exit(0);
}
结果是:
[cpp] view
plaincopy
123
因为unix系统中_exit 函数并不冲洗缓冲区。
作用:在实际编程中,I/O速度取决于显示器、键盘、硬盘等I/O设备的性能,而这些设备比起CPU和内存是比较慢的。因此系统采用缓冲区的方式来减少I/O的读写,以便提高系统性能。
I/O的缓冲区的种类:1、无缓冲;2、行缓冲;3、全缓冲。
一、行缓冲:
看一个例子:
[cpp] view
plaincopy
#include <stdio.h>
int main(void)
{
printf("123\n456");
while(1){}
return 0;
}
结果:
[cpp] view
plaincopy
123
这段代码只输出了“123\n”而没有输出“456”。原因是标准I/O:stdin,stdout是行缓冲。
行缓冲的特性是:C标准输出先写到行缓冲区里,当遇到下列四种情况才一次性把行缓冲区的数据写到I/O设备里去:
1、遇到\n字符;
2、行缓冲区(linux默认大小为1024字节)被填满后。
3、调用冲洗缓冲区的函数:fflush等。
4、进程返回、调用exit退出、文件流关闭等。
上例中printf的作用是把"123\n456"依次写入缓冲区,由于中途遇到\n,因此立即会把缓冲区里的所有数据——"123\n"写入I/O设备(此处是屏幕),接着的是把“456”写到缓冲区里。“456”之后没有“\n”、缓冲区又没有满、程序死循环在while(1)里没有结束,因此“456”将永远不会输出到I/O设备里。
属于行缓冲的I/O设备通常是需要交互的I/O:键盘(默认的stdin),屏幕(默认的stdout)等。
二、全缓冲
还是上面的代码(假设生成的执行程序名为“a.ex”,并且目录下有个“b.txt”的文本),如果这样启动:
[cpp] view
plaincopy
$ a.ex > b.txt
那么程序将不会输出任何字符到b.txt中。
因为对于文件(文件是在硬盘上的),硬盘I/O属于全缓冲。
全缓冲的特性是:C标准输出先写到全缓冲区里,当遇到下列三种情况才一次性把全缓冲区的数据写到I/O设备里去:
1、全缓冲区被填满后。
2、调用冲洗缓冲区的函数:fflush等。
3、进程返回、调用exit退出、文件流关闭等。
上例中启动a.ex程序时,用重定向符号“>”将stdout重定向到b.txt里。由于b.txt是文件,属于硬盘I/O,所以并满足全缓冲的写入条件。
属于全缓冲的I/O设备有:硬盘等。
三、无缓冲
[cpp] view
plaincopy
#include <stdio.h>
#include <unistd.h>
int main(void)
{
write(STDOUT_FILENO,"123\n456",7);
while(1){}
return 0;
}
结果是:
[cpp] view
plaincopy
123
456
没错,无缓冲会直接将字符串写入I/O设备里去。
write写文件或者屏幕等设备都是无缓冲的;stderr无论重定向到哪里都是无缓冲的。
四、最后补充一些注意:
[cpp] view
plaincopy
#include <unistd.h>
#include <stdio.h>
int main(void)
{
printf("123\n456");
_exit(0);
}
结果是:
[cpp] view
plaincopy
123
因为unix系统中_exit 函数并不冲洗缓冲区。
相关文章推荐
- linux目录与路径
- linux c/c++ 检测程序是否在运行
- 安装archlinux+cinnamon笔记
- Linux学习笔记-----RPM包管理----源码包安装
- linux学习之路(8)
- linux系统中scp命令的用法(Permission denied排错二例)
- linux学习之路(7)
- linux学习之软链接和硬链接
- linux学习之路(6)
- linux学习之路(5)
- Linux学习笔记----光盘yum源的搭建
- linux系统怎么截图?linux系统中对指定区域进行截图的详细教程
- linux学习之路(4)
- CentOS7防火墙
- Linux文件系统管理-常用命令df\du\fsck\dumpe2fs
- Linux下权限管理-文件系统属性权限chattr/sudo
- linux 下安装ssh
- linux下配置phpInterperter
- Linux下权限管理-文件特殊权限setUID/sticky BIT
- linux学习之路(3)