【操作系统】系统级IO
Contents
高级别的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
|
|
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