LINUX系统编程 关于SDTIO库缓冲区

简介: 我们知道标准C中的文件读取的函数比如printf,fwrite等函数,实际都是调用OS级别的 API,比如LINUX下就是wirte,read函数,而write read函数在用户态下是没有缓冲的, 当然在内核态有OS CACHE/OS BUFFER,所以某些...

我们知道标准C中的文件读取的函数比如printf,fwrite等函数,实际都是调用OS级别的
API,比如LINUX下就是wirte,read函数,而write read函数在用户态下是没有缓冲的,
当然在内核态有OS CACHE/OS BUFFER,所以某些直接调用wirte,read的程序肯定会
分配一个缓冲区,特别是O_DIRECT这种方式下,内核态的OS CACHE和OS BUFFER没用
这种情况下用户态的BUFFER显得更加重要,因为不可能一次读一个字节吧,那性能可想而知


而作为用户态空间的STDIO也是这样做的,它会为打开的文件分配缓存,默认应该是8192字节
如下图摘自UNIX系统编程手册 13章:


实际上我们可以使用setvbuf来设置某个打开文件的缓冲大小及模式。
我们来看看原型:
int setvbuf(FILE *stream, char *buf, int mode, size_t size);
返回0为成功,非零为失败
FILE *stream:打开文件的FILE*
char *buf:BUFFER的地址,如果为NULL,MODE为_IOLBF和_IOFBF则自动分配缓冲区
           如果为_IONBF则不分配缓冲区
int mode:_IONBF不使用缓冲区,立即调用write/read,忽略buf和size为NULL和0,stderr属于这个
          _IOLBF使用行缓冲I/O,终端设备默认为这种。要么遇到换行符要么缓冲满才调用write/read,
          stdin/stdout属于这个。
          _IOFBF采用全缓冲I/O,buffer满才调用write/read,磁盘I/O属于这个比如fwrite/fread
size_t size:缓冲大小


更简单函数setbuf原型如下:
void setbuf(FILE *stream, char *buf);
相当于
setvbuf(fp,buf,(buf !=NULL)?_IOFBF:_IONBF,BUFSIZ);


如果buf=NULL则_IONBF打开不带缓冲,或者调用全缓冲,BUFSIZ默认8192。
所以我们如果不想用缓冲直接:
setvbuf(fp,NULL)
即可。


现在回想一下fread
size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream);


fread的时候我们通常要calloc一块内存用于void *ptr,那么现在我们想一下实际
上这个数据正常缓存到了3个地方
1、用户分配的内存*ptr
2、STDIO的缓存默认8192
3、内核态OS CACHE
这视乎有点臃肿,我们可以想办法简化。事实上数据库软件有时候只使用了用户态
的一份缓存,而打开O_DIRECT来提高性能。


下面一个小程序可以验证打开和关闭stdout缓冲的区别:


int main(void)
{
        int i;
//      setbuf(stdout,NULL);


        for(i=0;i<10;i++)
        {
                printf("-");
                sleep(1);
        }


        printf("\n");
}


区别就是是否使用setbuf,如果使用setbuf则 -符号会一个一个输出,不使用会一起输出
这就是STDIO缓存在作怪。
相关文章
|
4天前
|
Linux 编译器 Android开发
FFmpeg开发笔记(九)Linux交叉编译Android的x265库
在Linux环境下,本文指导如何交叉编译x265的so库以适应Android。首先,需安装cmake和下载android-ndk-r21e。接着,下载x265源码,修改crosscompile.cmake的编译器设置。配置x265源码,使用指定的NDK路径,并在配置界面修改相关选项。随后,修改编译规则,编译并安装x265,调整pc描述文件并更新PKG_CONFIG_PATH。最后,修改FFmpeg配置脚本启用x265支持,编译安装FFmpeg,将生成的so文件导入Android工程,调整gradle配置以确保顺利运行。
24 1
FFmpeg开发笔记(九)Linux交叉编译Android的x265库
|
6天前
|
Ubuntu 安全 Linux
《Linux 简易速速上手小册》第1章: Linux 系统基础(2024 最新版)
《Linux 简易速速上手小册》第1章: Linux 系统基础(2024 最新版)
38 1
|
13天前
|
资源调度 JavaScript 搜索推荐
Linux系统之部署envlinks极简个人导航页
【4月更文挑战第11天】Linux系统之部署envlinks极简个人导航页
53 2
|
15天前
|
缓存 Linux 测试技术
安装【银河麒麟V10】linux系统--并挂载镜像
安装【银河麒麟V10】linux系统--并挂载镜像
81 0
|
15天前
|
监控 Unix Linux
Linux操作系统调优相关工具(四)查看Network运行状态 和系统整体运行状态
Linux操作系统调优相关工具(四)查看Network运行状态 和系统整体运行状态
30 0
|
13天前
|
存储 算法 Linux
【实战项目】网络编程:在Linux环境下基于opencv和socket的人脸识别系统--C++实现
【实战项目】网络编程:在Linux环境下基于opencv和socket的人脸识别系统--C++实现
38 6
|
1天前
|
Linux 数据安全/隐私保护
Linux系统忘记密码的三种解决办法
这篇博客介绍了三种在Linux忘记密码时重置登录密码的方法:1) 使用恢复模式,通过控制台界面以管理员权限更改密码;2) 利用Linux Live CD/USB启动,挂载硬盘分区并使用终端更改密码;3) 进入单用户模式,自动以管理员身份登录后重置密码。每个方法都提供了详细步骤,提醒用户在操作前备份重要数据。
|
1天前
|
JSON Unix Linux
Linux系统之jq工具的基本使用
Linux系统之jq工具的基本使用
10 1
|
1天前
|
数据采集 监控 安全
linux系统被×××后处理经历
linux系统被×××后处理经历
|
1天前
|
Ubuntu Linux
Linux(Ubuntu)系统临时IP以及静态IP配置(关闭、启动网卡等操作)
请注意,以上步骤是在临时基础上进行配置的。如果要永久保存静态IP地址,通常还需要修改 `/etc/network/interfaces`文件,以便在系统重启后保持配置。同时,确保备份相关配置文件以防止出现问题。
6 1