文章目录
一.缓冲区
int main()
{
printf("hello linux");
sleep(2);
return 0;
}
对于这样的代码,首先可以肯定的是printf
语句先于sleep
执行,既然如此那么就应该是先打印语句然后进行休眠,下面看看结果:
但这里却是先休眠以后再打印语句,这是因为存在一个叫缓冲区的东西,当我们要向外设写入数据(让显示器显示就是向显示器写入数据)时会将数据暂存至缓冲区,然后在根据缓冲区的刷新策略刷新。
先休眠再显示数据是因为我们并不是直接向外设写入数据,而休眠以后还能刷出数据是因为有缓冲区暂存数据。下面就来谈谈缓冲区。
1.什么是缓冲区
缓冲区的本质就是一块内存(物理内存)
2.缓冲区的意义
我是一个奇思妙想的手艺人,我有一个好朋友叫泰裤辣。每当我打造出一个东西的时候我都会骑着自行车跨越一百多公里去送给他。后来有一天,快递行业兴起了,我有新发明就不用再自己骑着自行车跨越山和大海去给他送了,我只要将我的东西交给快递点,就可以继续回家搞发明,东西有快递公司去给我送,这样就节省了我大量的时间。
那么我就是进程,我的好朋友泰裤辣就是文件,而我的新发明就是数据,缓冲区就是快递点。所以说缓冲区最大意义就在于节省发送者的时间,也就是节省进程的时间。因为外设是一个很慢的东西,当我们访问外设的时候大部分时间都是在等外设准备好,真正写入的时间占比很少。如果有缓冲区的存在,那么进程只要将数据交给缓冲区以后就可以返回去执行后续的代码,缓冲区帮进程承担了等外设准备好的时间代价。
3.缓冲区的刷新策略
但我去寄快递,往往都是我将东西交给快递点一段时间后我的东西才被快递点发出,因为如果一有人寄东西快递点就派车去送这样效率太低百分百亏钱。但是如果是在淡季,等了很长也没有多少人寄快递,快递点也不会说将你的东西留在他那里好几个月。而且如果你是寄一辆轿车大小或者等级的东西,快递点也是会根据你这个情况单次的将你的快递发出。所以虽然快递公司正常情况下是等货物累计要一定数量才发送,但是也会有特殊情况。
同理,缓冲区刷新也是一样,虽然效率最高的是缓冲区满了以后再一次将整个缓冲区中的数据刷新出去(又称全缓冲),但是这个刷新方式只在将数据刷新到磁盘文件上的时候才使用。
向显示器写入数据时,缓冲区采用的方式是行刷新(行缓冲)。这是因为显示器是给用户看的,而我们人的阅读习惯是按行从左到右读取,计算机本质就是给人使用的工具,所以在给显示器刷新的时候采用行刷新。
除了全缓冲和行缓冲以外,还有一种很少见的刷新方式叫无缓冲,也就是说一有数据写入就立马刷新出去。比如printf立马fflush
此外还有两种特殊的刷新方式:
1.用户强制刷新
2.进程退出;进程在退出之前为了防止缓冲区还有数据没被刷新出去导致数据丢失会再刷新一次缓冲区
4.我们目前谈论的缓冲区在哪里
#include<stdio.h>
#include<unistd.h>
#include<string.h>
int main()
{
//先写一批C语言函数接口
printf("hello printf\n");
fprintf(stdout,"hello fprintf\n");
fputs("hello fputs\n",stdout);
//再写一个系统调用
const char*s="hello write\n";
write(1,s,strlen(s));
fork();
return 0;