博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
linux系统IO操作
阅读量:3964 次
发布时间:2019-05-24

本文共 2185 字,大约阅读时间需要 7 分钟。

本文重点说明下面内容:

  • 什么是标准IO,什么是文件IO?
  • 什么是Direct IO? O_SYNC标识有什么意义?
  • 各个层面的缓存如何同步?
  • 还在page cache中的脏页可以读写吗?

IO路径上的各层buff

Application buff

|
clib buff
|
page cache
|
disk cache

标准IO

  • 标准IO操作的是流(File对象)
  • 标准IO可以设置缓存,这个缓存是用户态buffer,一般称为clib buff
    api
#include 
//打开流FILE *fopen(const char *pathname, const char *type);//关闭流int fclose(File *fp);// 刷新流int fflush(FILE *fp);// 一次读写一个字符int fgetc(FILE *fp);int fputc(FILE *fp);// 一次读写一行char* fgets(char* buf, int n, FILE* fp);int fputs(const char *str, FILE* fp);// 二进制读写size_t fread(void *ptr, size_t size, size_t nobj, FILE *fp);size_t fwrite(const void *ptr, size_t size, size_t nobj, FILE *fp);// 格式化输入输出int fprintf(FILE *fp, const char* format, ...);int fscanf(FILE *fp, const char *format, ...);// 示例#include
#include
int main(void){ char buf[1024]; while (fgets(buf, 1024, stdin) != NULL) if (fputs(buf, stdout) == EOF) printf("output error"); if (ferror(stdin)) printf("input error"); exit(0);}

说明

  • 调用fwrite, fputc, fputs系列函数后,数据被保存到clib buf中,依然处于用户态,如果此时应用进程crash掉,这些数据将丢失。
  • 在调用fflush可将clib buf中的数据写入内核的page cache中。
  • 调用fclose也会将clib buff中的数据刷新到内核,并且把clib buff中的输入数据丢弃。
    从这些标准IO的API可看出,标准IO比文件IO要简洁很多,没有各种标识,没有sync, nonblock等。
    上列API具体使用细节可参考《unix环境高级编程》第5章。

文件IO

文件IO是直接操作linux系统调用,大部分的问题都是使用文件IO带来的。

api

int open(const char *pathname, int oflag);int close(int filedes);ssize_t read(int filedes, void* buff, size_t nbytes);ssize_t write(int filedes, const void* buff, size_t nbytes);int fsync(int filedes);int fcntl(int filedes, int cmd);int ioctl(int filedes, int request);

说明

  • O_SYNC标识打开的文件,会在write系统调用时,会等待IO从底层返回;O_SYNC仅对写有意义。
  • O_DIRECT标识打开的文件不经过page cache; O_DIRECT对读写都是有意义的。
  • O_NONBLOCK标识打开的文件(一般是网络IO,终端设备IO) ,在不可读写时立即返回EAGAIN等错误码。
  • O_SYNC, O_DIRECT有区别如下,
size_t wirte_file(){    if(o_DIRECT)        direct_io();    else        buffered_io();    if( O_SYNC )        wait_data_synced();}
上述API细节可参考《unix环境高级编程》第3章。

mmap

api

#include 
void *mmap(void* addr, size_t length, int prot, int flags, int fd, off_t offset);
mmap在calling process的虚拟地址空间中创建一个映射,主要有以下两种常用方式:
  • 对文件创建一个mapping,读写文件可以用读写内存替代。

  • 匿名映射,传入的fd为-1

    创建mapping后,省掉了数据从在用户态buff和内核page cache的拷贝


后续整理下linux系统文件IO流程

转载地址:http://uyuki.baihongyu.com/

你可能感兴趣的文章
Mule ESB-Content-Based Routing Tutorial(3)
查看>>
年末项目经验总结
查看>>
做事情要放下面子,拿起责任
查看>>
敏捷开发实践(1)-故事工作量估算导致的问题
查看>>
记一次解决jenkins持续构建,自动部署的问题
查看>>
敏捷开发实践(2)-要不要文档?
查看>>
写博意味着什么
查看>>
比较Cint() , int() , fix() ,round()的区别
查看>>
举例说明常用字符串处理函数
查看>>
软件生存期模型
查看>>
制定计划(问题的定义,可行性研究)
查看>>
需求分析
查看>>
软件设计
查看>>
程序编码
查看>>
软件测试
查看>>
软件维护
查看>>
软件项目管理
查看>>
面向过程的分析方法
查看>>
软件设计基础
查看>>
UML的基本结构
查看>>