文章目录
- 缓冲区的认识
缓冲区的认识
上次我们已经介绍了缓冲区的刷新策略,并且遇到了一个问题,这次我们就继续延续上次的话题。
一般而言行缓冲的设备文件-------显示器文件
一般而言全缓冲的设备文件-------磁盘文件
所有设备永远倾向于全缓冲!—>缓冲区满了,才刷新—>需要I/O的次数就较少—>提高了效率---->和外设进行I/O的时候,数据量的大小不是主要矛盾
,我们和外设预备I/O的过程才是最耗费时间的!
那么显示器为什么是行刷新?因为显示器是直接给用户看的,一方面要照顾效率,一方面要照顾用户体验。
极端情况下,用户可以自定义刷新规则。
回答之前遇到的问题。
我们看到同一个程序,向显示器打印输出了4行文本。
用重定向的方法向普通文件(磁盘上的)打印的时候,变成了7行。
其中
C语言:每个接口打印2次
OS:每个接口打印1次
上篇博客我们知道是由fork引起的。但是fork之前所有代码已经执行完了啊,fork之后就应该没数据了啊,为什么还有?
因为fork之前的代码已经执行完了,但并不代表数据已经刷新了。
但是我们从上面有可以知道不管有没有fork,都并不影响系统接口。
那么缓冲区是由谁维护呢?
我们可以知道缓冲区绝对不是由OS提供的。如果由OS提供提供,那么上面代码表现的现象应该一样。
C接口:
1.如果想显示器打印则刷新策略就是行刷新,那么最后执行fork的时候------一定是函数执行完了 并且 数据一定是被刷新了。----则fork就无意义了
2.如果对应程序进行了重定向,要向磁盘文件打印,那么隐形的刷新策略就变成了全缓冲,那么每行的’\n’便没有意义。
fork的时候一定是数据执行完了,但是数据还没有刷新。-----在当前进程对应的C标准库的缓冲区!
这部分的数据是不是父进程数据?是的。
那么刷新策略是不是写入的过程?是的。
所以fork的时候数据发生了写时拷贝,所以数据打印了2次。
C标准库给我们提供的用户级缓冲区!还有内核级缓冲区。
用户级缓冲区在哪里?
我们来看一段代码
我们看到加了fflush(stdout)重定向也变成4条了,fflush我们之前学过,就是强制刷新缓冲区。
但是为什么fflush中,只传入stdout就可以了呢?
C语言打开文件
FILE* fopen(const cahr* path,const char* mode);
我们是到FILE*指向的struct FILE 结构体一定封装了fd,但是只封装了fd吗?
不只是包含了fd,还有该fd文件对应的语言层缓冲区。
//缓冲区相关
/* The following pointers correspond to the C++ streambuf protocol. */
/* Note: Tk uses the _IO_read_ptr and _IO_read_end fields directly. */
char* _IO_read_ptr; /* Current read pointer */
char* _IO_read_end; /* End of get area. */
char* _IO_read_base; /* Start of putback+get area. */
char* _IO_write_base; /* Start of put area. */
char* _IO_write_ptr; /* Current put pointer. */
char* _IO_write_end; /* End of put area. */
char* _IO_buf_base; /* Start of reserve area. */
char* _IO_buf_end; /* End of reserve area. */
/* The following fields are used to support backing up and undo. */
char *_IO_save_base; /* Pointer to start of non-current get area. */
char *_IO_backup_base; /* Pointer to first valid character of backup area */
char *_IO_save_end; /* Pointer to end of non-current get area. */
所以缓冲区在C语言的FILE文件中。
C语言有缓冲区,C++也有,缓冲区在cout重载的operator<<()函数中。