fread,fwrite数据写入磁盘的流程

1、fwrite,fflush

fread,fwrite>> CLib buffer内存缓冲(用户空间) -->fflush>>page  cache内核缓冲--->fsync>>磁盘

fflush:标准I/O函数(如:fread,fwrite)会在内存建立缓冲,该函数刷新内存缓冲,将内容写入内核缓冲,要想将其写入磁盘,还需要调用fsync。(先调用fflush后调用fsync,否则不起作用)。

https://blog.csdn.net/lhb0709/article/details/86077584

https://blog.csdn.net/zhangxiong2532/article/details/50608898

调用fwrite后,把数据从application buffer 拷贝到了 CLib buffer,即C库标准IObuffer。fwrite返回后,数据还在CLib buffer,如果这时候进程core掉。这些数据会丢失。没有写到磁盘介质上。当调用fclose的时候,fclose调用会把这些数据刷新到磁盘介质上。除了fclose方法外,还有一个主动刷新操作fflush 函数,不过fflush函数只是把数据从CLib buffer 拷贝到page  cache 中,并没有刷新到磁盘上,从page cache刷新到磁盘上可以通过调用fsync函数完成。 

从上面类子看到,一个常用的fwrite函数过程,基本上历经千辛万苦,数据经过多次copy,才到达目的地。有人心生疑问,这样会提高性能吗,反而会降低性能吧。这个问题先放一放。

有人说,我不想通过fwrite+fflush这样组合,我想直接写到page cache。这就是我们常见的文件IO调用read/write函数。这些函数基本上是一个函数对应着一个系统调用,如sys_read/sys_write. 调用write函数,是直接通过系统调用把数据从应用层拷贝到内核层,从application buffer 拷贝到 page cache 中。

2、关于linux系统调用write()

调用一次write()完毕,是不是已经写到磁盘上了?
是不是调用一次write(),就是一次写请求,不管写多少个字符进去,调用完都已经通过缓冲区写到磁盘上了?
那么fsync()这个函数是不是指将缓冲区的写到磁盘上,如果是,write完再fsync是不是多此一举?
我想实现的是可以先创建一个文件,然后写一些东西到该文件的缓冲区,再调用fsync()写入磁盘,请问如何实现?

当你用write之后,内核就响应write系统调用sys_write,然后向高速磁盘缓冲块page  cache写入数据,之后,你如果用stat,或者read时,系统首先会在高速缓冲块中去查看相应的数据是否在块中,如果不是,然后再调用磁盘驱动加载磁盘数据到高速缓冲块中,然后再由高速缓冲块中返回你要的数据!!!!!这就是你用stat()输出st_size,就是写入的个数的原因!!!!!
系统会在合适的时机再向真正的硬件写入高速缓冲块中的数据,也可以用fsync强制把高速缓冲块中的相应数据写入磁盘!!!!!!!          

https://www.169it.com/tech-qa-linux/article-784884903592209928.html

https://blog.csdn.net/xiaofei0859/article/details/51145051

3、fwrite和write的区别

fwrite是ANSI C的写函数,带缓冲(应用层缓冲);write/read是POSIX 的写函数,不带缓冲(应用层缓冲)。请问:

1. 带不带缓冲是指什么意思??

fwrite-->clib buffer-->pagecache-->……

write-->pagecache-->……

 2. 既然write不带缓冲,为什么write(int fd, const void *buf, size_t count) 是把缓冲区的字节写入fd相关联的文件中,read(int fd, void *buf, size_t count),是将fd关联的文件读入到缓冲区buf中?? 

首先要明白不带缓冲的概念:

所谓不带缓冲,并不是指内核不提供缓冲,而是只单纯的系统调用,不是函数库的调用。系统内核对磁盘的读写都会提供一个块缓冲,当用write函数对其写数据时,直接调用系统调用,将数据写入到块缓冲进行排队,当块缓冲达到一定的量时,才会把数据写入磁盘。因此所谓的不带缓冲的I/O是指进程不提供缓冲功能。

每调用一次write或read函数,直接系统调用。
而带缓冲的I/O是指进程对输入输出流进行了改进,提供了一个流缓冲,当用fwrite函数网磁盘写数据时,先把数据写入流缓冲区中,当达到一定条件,比如流缓冲区满了,或刷新流缓冲,这时候才会把数据一次送往内核提供的块缓冲,再经块缓冲写入磁盘 

fwrite是带缓冲的,write不带缓冲。

举例说明如下:
如果文件的大小是8k。
若用write,且只分配了2k的缓存,则要将此文件读入需要做4次系统调用。(内核空间和用户空间切换4次)
若用fwrite,则系统自动分配缓存,则读入此文件只要一次系统调用。
也就是用write要读4次磁盘,而用fwrite则只要读1次磁盘。所以fwrite的效率比write要高4倍。

另外,如果程序对内存有限制,则用write比较好。
系统调用write的效率取决于用户buff的大小和要写入的总数量,如果buff太小,进入内核空间的次数会增加,效率就低下。而fwrite会自动完成缓存分配任务,减少了实际出现的系统调用,所以效率比较高。 

所谓缓冲区,就是一段内存。里面存有内容。fwrite有缓冲,代表当fwrite调用结束之后,它所要求写入文件的内容,可能还有一部分在内存当中,如果要确保写入,需要调用fflush。


 

猜你喜欢

转载自blog.csdn.net/liuxiao723846/article/details/120925213