2019-10-7 linux缓冲区问题


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)

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值