跳转至内容
  • 版块
  • 最新
  • 标签
  • 热门
  • Online Tools
  • 用户
  • 群组
折叠
品牌标识

D2Learn Forums

  1. 主页
  2. SubForums
  3. 现代C++ | mcpp论坛
  4. Linux系统编程(1)文件

Linux系统编程(1)文件

已定时 已固定 已锁定 已移动 现代C++ | mcpp论坛
linux 系统编程
1 帖子 1 发布者 18 浏览
  • 从旧到新
  • 从新到旧
  • 最多赞同
登录后回复
此主题已被删除。只有拥有主题管理权限的用户可以查看。
  • 月 离线
    月 离线
    月仁不吃五饼
    编写于 最后由 编辑
    #1

    Linux系统编程(1)文件操作的层次结构

    我将在此持续更新Linux系统编程的教学,有不妥,不正确的地方望看到的人指正

    首先对于IO的操作,或者各种IO函数,他应当可以被分为下述的几个部分,我将采用总分的结构,在系统描述每一个部分之前,先对整个linux IO有一个大致的认识

    第 0 层:用户态缓冲 I/O(不是系统调用,但最“上层”)

    特点:你操作的是 FILE*,数据先进入 用户态缓冲区,再由 libc 在合适时机调用 write/read 等进入内核。
    典型 API:fopen/fclose/fread/fwrite/fgets/fputs/fgetc/fputc/printf/scanf,setvbuf/fflush/ferror/feof
    要点:这层决定“行缓冲/全缓冲/无缓冲”,以及很多“看起来一次写入”,底下可能拆成多次系统调用。

    第 1 层:文件描述符(fd)上的“无缓冲”I/O 系统调用(VFS 入口)

    特点:你提供用户缓冲区地址,内核负责把数据在 用户内存 ↔ 内核 间拷贝,并通过 VFS/页缓存/文件系统把它落到磁盘或读出来。

    1.1 基础数据读写

    • open/openat/creat, close

    • read, write

    • lseek(改变文件偏移)

    1.2 更“语义化/性能化”的读写

    • 定位读写(不改文件偏移):pread, pwrite

    • 向量 I/O(scatter/gather):readv, writev

    • 按大小截断:truncate, ftruncate

    这一层是“系统编程”的主干:大多数 I/O 都能归结为这些 fd syscalls 的组合。

    第 2 层:内核缓冲/页缓存语义相关(同样还是 fd 接口,但语义更“接近内核缓存”)

    特点:你不只是“读写字节”,还在控制“什么时候算写成功、什么时候必须落盘、缓存如何使用”。

    2.1 同步与持久化

    • fsync, fdatasync, sync, syncfs
      解决“写进页缓存了但还没真正落盘”的一致性/崩溃恢复问题。

    2.2 访问模式与预取/淘汰建议(属于“提示/策略”)

    • posix_fadvise(libc 封装,底层可能用 fcntl/内核建议路径)

    • readahead(Linux 专有,提示预读)

    这类接口不一定“立刻改变数据”,但会影响页缓存、预读、回写策略,从而影响性能与时延。

    第 3 层:绕开“显式 read/write”的 I/O 路径

    3.1 内存映射 I/O(mmap 路径)

    特点:文件数据映射到进程虚拟内存,通过缺页异常把页拉进来;写回由回写机制处理。

    • mmap, munmap, msync(以及 mprotect/mlock 等相关)

    直觉:read/write 是“你显式搬运”,mmap 是“让内核分页系统替你搬运”。

    3.2 零拷贝/内核内搬运(减少 user<->kernel 拷贝)

    • sendfile(文件→socket 常用)

    • splice, tee, vmsplice(在 fd 之间搬运/管道相关)

    第 4 层:I/O 多路复用与事件驱动(“等 I/O”也是 I/O 的一部分)

    特点:面向大量 fd 时,不是忙等,而是让内核告诉你“哪个 fd 可读/可写/出错”。

    • select, pselect

    • poll, ppoll

    • epoll_create/epoll_ctl/epoll_wait

    (扩展:inotify 用于文件系统事件通知,也常被归到“事件 I/O”这一层。)

    第 5 层:异步 I/O(发起后不阻塞当前线程)

    特点:读写请求提交给内核,之后再取完成事件;适合高并发、减少线程阻塞。

    • POSIX AIO:aio_read/aio_write/aio_error/aio_return(多为库接口,底层实现依系统而异)

    • Linux AIO:io_setup/io_submit/io_getevents(更“Linux 内核味”)

    更现代的 io_uring 也属于这一类(但它比 Love 那本书年代新很多,书里大概率没有重点展开)。

    第 6 层:控制类系统调用(不直接搬运数据,但决定“怎么 I/O”)

    6.1 文件描述符控制与状态

    • fcntl:设置/获取 fd 标志(如 O_NONBLOCK)、记录锁(F_SETLK 等)、复制 fd 等

    • dup/dup2/dup3

    6.2 设备/驱动专用控制面(“像 I/O,但本质是控制”)

    • ioctl:字符设备/块设备/终端/网络设备等大量控制都走它

    第 7 层:命名空间与元数据 I/O(“文件系统操作”,不等于数据读写)

    特点:改的是目录项、inode 元数据、权限、链接关系;不直接等价于读写文件内容。

    • 元数据查询:stat/fstat/lstat

    • 权限属主:chmod/fchmod, chown/fchown, umask, access

    • 链接与重命名:link/unlink/symlink/readlink, rename

    • 目录与节点:mkdir/rmdir, mknod

    • 目录读取:getdents(系统调用层),上层常用 opendir/readdir(库封装)

    总体结构如下

    ┌───────────────────────────────────────────────────────────────────────────┐
    │                         USER SPACE                                        │
    │                                                                           │
    │  ┌─────────────────────────────────────────────────────────────────────┐ │
    │  │ Level 0: User-mode Buffering (glibc FILE*)                            │ │
    │  │                                                                     │ │
    │  │  fopen / fread / fwrite / printf                                     │ │
    │  │  ┌──────────────────────────┐   ┌──────────────────────────────┐   │ │
    │  │  │ User Buffer (glibc)       │   │ Line / Full Buffering         │   │ │
    │  │  └──────────────────────────┘   └──────────────────────────────┘   │ │
    │  └─────────────────────────────────────────────────────────────────────┘ │
    │                                                                           │
    ├──────────────────── SYSTEM CALL INTERFACE / BOUNDARY ─────────────────────┤
    │                                                                           │
    │                         KERNEL SPACE                                      │
    │                                                                           │
    │  ┌─────────────────────────────────────────────────────────────────────┐ │
    │  │ Level 1: FD Standard Syscalls & VFS Entry                             │ │
    │  │                                                                     │ │
    │  │   open / read / write                                                 │ │
    │  │   ┌───────────────────────┐    ┌───────────────────────────────┐   │ │
    │  │   │ User → Kernel Copy     │    │ VFS (file / inode / dentry)    │   │ │
    │  │   └───────────────────────┘    └───────────────────────────────┘   │ │
    │  └─────────────────────────────────────────────────────────────────────┘ │
    │                                                                           │
    │  ┌───────────────────────┐   ┌──────────────────────────┐   ┌─────────┐ │
    │  │ Level 3: Zero-copy     │   │ Level 2: Page Cache      │   │ Level 4 │ │
    │  │ mmap / sendfile /     │   │ fsync / fdatasync        │   │ epoll   │ │
    │  │ splice                │   │ readahead               │   │ poll    │ │
    │  └───────────────────────┘   └──────────────────────────┘   └─────────┘ │
    │                                                                           │
    │                              │                          │               │
    │                              ▼                          ▼               │
    │                    ┌──────────────────────────┐   ┌───────────────┐   │
    │                    │ Level 5: Async I/O       │   │ Level 6:       │   │
    │                    │ AIO / io_uring           │   │ fcntl / ioctl  │   │
    │                    └──────────────────────────┘   └───────────────┘   │
    │                                                                           │
    │  ┌─────────────────────────────────────────────────────────────────────┐ │
    │  │ Level 7: Metadata & Namespace Ops                                    │ │
    │  │                                                                     │ │
    │  │   stat / chmod / rename                                              │ │
    │  └─────────────────────────────────────────────────────────────────────┘ │
    │                                                                           │
    │  ┌─────────────────────────────────────────────────────────────────────┐ │
    │  │ Block Device Drivers & I/O Scheduler                                 │ │
    │  │   (bio / request / elevator)                                        │ │
    │  └─────────────────────────────────────────────────────────────────────┘ │
    │                                                                           │
    │                 ↓                    ↓                     ↓             │
    │                                                                           │
    │  ┌─────────────────────────────────────────────────────────────────────┐ │
    │  │ HARDWARE STORAGE (Disk / SSD / NVMe)                                 │ │
    │  └─────────────────────────────────────────────────────────────────────┘ │
    │                                                                           │
    └───────────────────────────────────────────────────────────────────────────┘
    

    用户操作缓冲IO结构

    ┌──────────────────────────────────────────────────────────────────────────────┐
    │                              USER SPACE                                      │
    │                                                                              │
    │  ┌────────────────────────────────────────────────────────────────────────┐ │
    │  │ Level 0: User-mode Buffering (glibc FILE*)                               │ │
    │  │                                                                        │ │
    │  │  Application calls:                                                    │ │
    │  │    fopen(path, mode)                                                   │ │
    │  │        │                                                               │ │
    │  │        ▼                                                               │ │
    │  │  glibc fopen implementation                                            │ │
    │  │  ┌──────────────────────────────────────────────────────────────────┐ │ │
    │  │  │ FILE struct                                                       │ │ │
    │  │  │                                                                  │ │ │
    │  │  │  int fd  ────────────────┐                                       │ │ │
    │  │  │  User-mode Buffer        │ char* base / ptr / size               │ │ │
    │  │  │  Flags (mode, buffering) │ line / full / none                    │ │ │
    │  │  └──────────────────────────────────────────────────────────────────┘ │ │
    │  │        │                                                               │ │
    │  │        └── returns FILE* fp                                            │ │
    │  │                                                                        │ │
    │  │  Application I/O:                                                      │ │
    │  │                                                                        │ │
    │  │  fwrite(ptr, size, nmemb, fp)                                          │ │
    │  │  fread (ptr, size, nmemb, fp)                                          │ │
    │  │        │                                                               │ │
    │  │        ▼                                                               │ │
    │  │  ┌──────────────────────────────────────────────────────────────────┐ │ │
    │  │  │ User-mode Buffer (glibc memory)                                   │ │ │
    │  │  │                                                                  │ │ │
    │  │  │  [ data ][ data ][ data ][ .... ][ free space ]                  │ │ │
    │  │  │                                                                  │ │ │
    │  │  │  Data copied between application buffer and libc buffer          │ │ │
    │  │  └──────────────────────────────────────────────────────────────────┘ │ │
    │  │        │                                                               │ │
    │  │        │  (buffer full / fflush)                                      │ │
    │  │        ▼                                                               │ │
    ├──────────────────────── SYSTEM CALL INTERFACE / BOUNDARY ────────────────────┤
    │                                                                              │
    │                              KERNEL SPACE                                    │
    │                                                                              │
    │  ┌───────────────────────────────┐     ┌───────────────────────────────┐   │
    │  │ open(path, flags, mode)       │     │ write(fd, buffer, count)       │   │
    │  │ System Call                   │     │ read (fd, buffer, count)       │   │
    │  └───────────────────────────────┘     └───────────────────────────────┘   │
    │             │                                 │                              │
    │             ▼                                 ▼                              │
    │  ┌────────────────────────────────────────────────────────────────────────┐ │
    │  │ Kernel Page Cache (VFS)                                                 │ │
    │  │                                                                        │ │
    │  │  - file / inode / dentry                                               │ │
    │  │  - page cache                                                         │ │
    │  │  - readahead / writeback                                              │ │
    │  └────────────────────────────────────────────────────────────────────────┘ │
    │             │                                                               │
    │             ▼                                                               │
    │  ┌────────────────────────────────────────────────────────────────────────┐ │
    │  │ Block Device Driver                                                    │ │
    │  │                                                                        │ │
    │  │  - bio / request                                                      │ │
    │  │  - I/O scheduler                                                      │ │
    │  └────────────────────────────────────────────────────────────────────────┘ │
    │             │                                                               │
    │             ▼                                                               │
    │  ┌────────────────────────────────────────────────────────────────────────┐ │
    │  │ HARDWARE STORAGE (Disk / SSD / NVMe)                                   │ │
    │  └────────────────────────────────────────────────────────────────────────┘ │
    │                                                                              │
    └──────────────────────────────────────────────────────────────────────────────┘
    

    其大致结构基本如下,后续,将对每一个模块进行详细系统的论述

    1 条回复 最后回复
    1

    • 登录

    • 没有帐号? 注册

    • 登录或注册以进行搜索。
    d2learn forums Powered by NodeBB
    • 第一个帖子
      最后一个帖子
    0
    • 版块
    • 最新
    • 标签
    • 热门
    • Online Tools
    • 用户
    • 群组