linux 知识库

第十章 系统级I/O

2018-02-26  本文已影响10人  ShutLove

一、I/O

  1. 对于Unix系统来说,所有IO设备,如磁盘、鼠标键盘、网卡,一切皆文件。这样的一个好处就是对于任何东西的输入输出,都可以抽象为对文件的读和写操作,即I/O。
  2. 既然都可以抽象为对文件的IO操作,操作系统在Unix内核上对外提供了一些Unix I/O调用,包括open、close、read、write、lseek和stat。
  3. Unix I/O对于频繁读取某个IO设备一个字节的情景性能较低,因此大多数编程语言基于Unix IO提供了标准IO库,标准IO库通过缓冲区的设计解决了频繁读取磁盘效率低下的问题。

二、文件

  1. 文件类型包含文本文件(linux以\n作为换行符)、二进制文件、目录、套接字(socket)、命名管道、符号链接、块设备等。
  2. 当进程打开一个文件时,如果调用成功,内核返回一个描述符,这个描述符是一个非负整数。linux shell创建的每个进程开始时都有三个打开的文件:标准输入(描述符0)、标准输出(描述符1)、标准错误(描述符2)。
  3. 关闭文件时,内核会释放在打开文件时创建的数据结构,并将这个文件描述符恢复到可用的描述符池中。
  4. 内核用三个数据结构表示打开的文件:
    描述符表:每个进程都有自己独立的描述符表,表项的key是打开文件时内核返回的描述符fd,value执行文件表中的表项。
    文件表:被所有进程共享,表项中包含当前文件位置(读写文件时用到)、引用计数(当前被多少个描述符表引用)、一个指向v-node表的指针。
    v-node表:所有进程共享,每个表项包含文件stat结构中的大多数信息,比如文件大小、文件类型、文件最近被访问时间等。
  5. 一个进程可以通过多个描述符访问多个文件,也可以通过多个描述符访问同一个文件,当访问同一个文件时,由于不同文件表的文件位置不同,因此不同文件描述符对同一个文件的读写互不影响。
  6. 文件共享:父子进程共享文件,是因为子进程复制了父进程的描述符表,所以父子进程实际都指向了相同的文件表。
  7. I/O重定向:底层是通过dup2(oldFd, newFd)函数实现,dup2函数会把oldFd表项复制到newFd表项。
    输出重定向:dup(4, 1),会把原本要写到标准输出的描述符表项1指向4,因此后续输出会写到描述符4指向的文件。
    输入重定向:dup(4, 0),描述符4会覆盖描述符0(标准输入),因此原本从标准输入读取的操作会转向从描述符4指向的文件读取。
上一篇下一篇

猜你喜欢

热点阅读