【操作系统】系统级IO

高级别的IO程序,如c中的printf和scanf,c++中的>><<,都依赖Unix 系统级IO

CSAPP Ch-10 笔记

Unix IO

Linux文件即是m个字节的序列$B_0, B_1, …, B_k, …, B_{m-1}$

所有的IO设备(网络,磁盘,终端)被抽象为文件,输入和输出被作为相应文件的读和写进行,Linux内核只需要暴露一个简单低级的应用接口

输入和输出的统一方式:

  • 打开文件:应用程序请求IO设备,内核返回描述符
  • Linux Shell创建的进程开始时有三个文件:标准输入0,标准输出1,标准错误2
  • 改变当前的文件位置:内核存储文件位置k,初始为0,通过seek改变这个偏移量
  • 读写文件:读为复制字节到内存,当k>=m时,会触发EOF条件;写为复制字节到一个文件中,从当前位置k开始,然后更新k
  • 关闭文件:通知内核,内核释放文件打开时创建的数据结构,释放描述符,进程终止时内核会释放打开的文件以及内存

文件

  • 普通文件:文本文件:ASCII或Unicode字符文件,其他的都是二进制文件,对内核而言无区别,换行符\n对应ASCII LF
  • 目录:包含一组链接的文件,链接将文件名映射到一个文件
  • 套接字socket:与另一个进程进行跨网络通信的文件
  • 命名通道named pipe,符号链接,字符和块设备

绝对路径:以斜杠开始/home/test

相对路径:以文件名开始,../test

打开和关闭文件

open函数打开或创建文件

返回一个文件描述符,在进程中没有打开的最小描述符 几种控制参数flags

1
2
3
4
5
6
O_RDONLY 只读
O_WRONLY 只写
O_RDWR 可读可写
O_CREAT 文件不存在则创建空文件
O_TRUNC 存在则截断,清空
O_APPEND 追加写入

mode参数控制读写权限

每个进程都有umask

访问权限为mode & ~umask

close(int fd)关闭文件,成功返回0,失败-1

读写文件

read和write

输入的size为unsigned long类型,ssize_t为long类型,因为read和write函数需要返回-1

read和write读写遇到不足的情况:

  • 读取时遇到EOF
  • 从终端读文本行
  • 读写socket:网络延迟导致read和write返回值不足

RIO包 Robust IO

读取文件元数据

stat和fstat函数,读取文件信息

读取目录内容

opendir函数

共享文件

  • 描述符表,每个进程之间独立
  • 文件表,打开文件的集合,所有进程共享,包含文件位置,引用计数,指向vnode表的指针,当引用计数为0时,操作系统删除表项
  • v-node,进程间共享,包含stat中的信息,st mode,st size

IO重定向

标准输出重定向到磁盘文件

覆盖写入文件之前的内容

使用dup2函数,将终端的输出关闭,改为磁盘文件,磁盘文件引用次数+1

标准IO

标准IO将打开的文件模型化为一个流,减少系统级IO操作的调用

第一次getc调用IO read函数读取到缓冲区,之后调用将缓冲区第一个字节返回给应用程序

选取IO函数问题

socket中不要使用标准IO,可能会导致崩溃,使用RIO函数/Unix IO

0%