layout: post
title: “linux缓冲区”
date: 2019-10-07
categories: linux
tags: linux
缓冲区的作用
struct _IO_FILE {
int _flags; /* High-order word is _IO_MAGIC; rest is flags. */
#define _IO_file_flags _flags
/* 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. */
struct _IO_marker *_markers;
struct _IO_FILE *_chain;
int _fileno;
int _blksize;
_IO_off_t _old_offset; /* This used to be _offset but it's too small. */
#define __HAVE_COLUMN /* temporary */
/* 1+column number of pbase(); 0 is unknown. */
unsigned short _cur_column;
signed char _vtable_offset;
char _shortbuf[1];
/* char* _save_gptr; char* _save_egptr; */
_IO_lock_t *_lock;
#ifdef _IO_USE_OLD_IO_FILE
};
struct _IO_FILE 结构体是文件标准IO结构体,即文件描述符表:
这个表是由链表组成的,每个结点都是struct _IO_FILE结构体:
无缓冲I/O :不是内核不提供缓冲,而是对于用户层来说,没有提供缓存,而对内核来说还是有缓存的
数据:数据流->内核缓存->磁盘
有缓冲I/O:是指在用户层上再建立了一层缓存区(流缓存区),目的是为了减少read,write等系统调用的使用次数,降低系统开销。
数据:数据流->流缓存区->内核缓存->磁盘
(1)缓冲区机制
非缓冲的文件操作访问方式,每次对文件进行一次读写操作时,都需要使用读写系统调用来处理此操作,即需要执行一次系统调用,执行一次系统调用将涉及到CPU状态的切换,即从用户空间切换到内核空间,实现进程上下文的切换,这将损耗一定的CPU时间,频繁的磁盘访问对程序的执行效率造成很大的影响。
ANSI标准C库函数 是建立在底层的系统调用之上,即C函数库文件访问函数的实现中使用了低级文件I/O系统调用,ANSI标准C库中的文件处理函数为了减少使用系统调用的次数,提高效率,采用缓冲机制,这样,可以在磁盘文件进行操作时,可以一次从文件中读出大量的数据到缓冲区中,以后对这部分的访问就不需要再使用系统调用了,即需要少量的CPU状态切换,提高了效率。
(2)缓冲类型
标准I/O提供了3种类型的缓冲区。
-
全缓冲区
BUFSIZE 默认大小 8192
fflush 刷新流(清空缓冲区)
默认开启 -
行缓冲区
遇到换行符才进行刷新默认行缓冲区的大小为1024
-
无缓冲区
read
write
strerr
指定缓冲区:
setbuf
函数:void setbuf(FILE *steam, char *buf);
功 能: 把缓冲区与流相联
说明:setbuf函数具有打开和关闭缓冲机制。为了带缓冲进行I/O,参数buf必须指向一个长度为BUFSIZ(定义在stdio.h头文件中)的缓冲区。通常在此之后该流就是全缓冲的,但是如果该流与一个终端设备相关,那么某些系统也可以将其设置为行缓冲。为了关闭缓冲,可以将buf参数设置为NULL。
setbuffer
函数:void setbuffer(FILE * stream,char * buf,size_t size);
功能:设置文件流的缓冲区
说明:参数stream为指定的文件流,参数buf指向自定的缓冲区起始地址,参数size为缓冲区大小。
setvbuf
函数:int setvbuf(FILE *stream, char *buf, int type, unsigned size);
参数:
type : 期望缓冲区的类型:
#define _IOFBF 0 /* Fully buffered.*/
#define _IOLBF 1 /* Line buffered. */
#define _IONBF 2 /* No buffering. */
size : 缓冲区内字节的数量。如果指定一个不带缓冲区的流,则忽略buf和size参数。
注:在打开流后,IO前需立即调用
课外:
还想深入了解,可以看看这个blog
2 /* No buffering. */
size : 缓冲区内字节的数量。如果指定一个不带缓冲区的流,则忽略buf和size参数。
注:在打开流后,IO前需立即调用
课外:
还想深入了解,可以看看这个blog
Linux高速缓冲区原理](https://www.cnblogs.com/alantu2018/p/8447411.html)