您的位置:首页 > 运维架构 > Linux

Linux系统编程第13章-文件I/O缓冲

2017-04-09 23:09 120 查看
1.对于IO,内核会维持一个缓冲,当调用read或者write系统调用时,不是直接写入磁盘或者从磁盘读取,而是先写入内核缓冲区,或者从内核缓冲区读取,内核会找合适的时机将缓冲区的数据写入磁盘。这样就可以减少磁盘操作,实现系统调用的快速返回。

2.stdio库的缓冲:

标准C语言的IO函数库stdio在user space提供了一个cache,用来减少系统调用的次数。当调用stdio的函数库比如fwrite,会将数据暂时写入自己的缓存,等达到一定的数量,再调用系统调用写入内核。

stdio库提供了函数可以设置缓冲的形式:

#include <stdio.h>
int setvbuf(FILE *stream, char *buf, int mode, size_t size);//return 0 success.


FILE为打开的文件,buf为预先分配的内存,如果设置为NULL,则系统会自动分配一块内存。size为buf的大小。mode为_IONBF(不进行io缓冲),_IOLBF(行缓冲,每一行缓冲一次), _IOFBF(全缓冲,buf满的时候调用系统调用).

#include <stdio.h>
void setbuf(FILE *stream, char *buf);
相当于调用如下:
setvbuf(stream, (buf != NULL) ? _IOFBF : _IONBF, BUFSIZE);//BUFSIZE定义于stdio.h文件。
还有一个系统调用,可以指定size:
#define _BSD_SOURCE
void setbuffer(FILE *strem, char *buf, size_t size);


刷新stdio缓冲区:

#include <stdio.h>
int fflush(FILE *stream)//将stdio的缓存刷入内核,如果stream为NULL,则刷新所有stdio缓冲区。


3.控制文件IO的内核缓冲:

IO同步分两种情况,

a.数据完整:只把数据和数据有关的信息同步到磁盘

b.文件完整:将所有的数据和文件信息都同步到磁盘

#include <unistd.h>
int fsync(int fd);//将内核缓冲中的数据同步到磁盘,同步到文件完整状态。
int fdatasync(int fd);//同步到数据完整状态
void sync(void)//会使包含更新文件信息的所有内核缓冲区刷新到磁盘上,


在open系统调用的时候也有sync的标志位。

fd = open(pathname, O_WRONLY | O_SYNC);//此标志位会在每次write系统调用的时候将数据刷新到磁盘,达到文件完整状态。一般不建议用,对系统性能影响非常大。另外除了O_SYNC标志位,还提供了两个更细致化的标志位O_DSYNC(同步到数据完整状态), O_RSYNC(读操作时保持数据完整状态)


4.就IO模式向内核提出建议:

#define _XOPEN_SOURCE 600
#include <fcntl.h>


int posix_fadvise(int fd, off_t offset, off_t len, int advice);//可以利用此函数来向内核建议缓存的大小。P201

5.绕过缓冲区告诉缓存,直接IO

在open时可以指定O_DIRECT标志,则会实现直接IO.一般不用,对系统性能影响巨大。

6.混合使用库函数和系统调用进行文件IO

#include <stdio.h>
int fileno(FILE *stream)//从FILE获得fd。下面函数是从fd获得stdio的FILE流。
FILE *fdopen(int fd, const char *mode)//mode参数与fopen函数中的mode参数含义相同,需要与fd的mode保持一致,不然会失败。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  linux