【深入理解计算机系统】系统级I/O

输入/输出I/O)是在主存和外部设备(例如磁盘驱动器、终端和网络)之间复制数据的过程。输入操作是从I/O设备复制数据到主存,输出操作是从主存复制数据到I/O设备。

在Linux系统中,通过使用由内核提供的系统级Unix I/O函数来实现较高级别的I/O函数

Unix I/O

一个Linux文件就是一个m个字节的序列,所有I/O设备(例如网络、磁盘和终端)都被模型化为文件,而所有输入和输出都被当作对相应文件的读和写来执行。这中将设备优雅的映射为文件的方式,允许Linux内核引出一个简单、低级的应用接口,简称Unix I/O, 这使得所有的输入和输出都能以一种统一且一致的方式来执行:

  1. 打开文件一个应用程序通过要求内核打开相应的文件,来告诉它想要访问的I/O设备。内核返回一个小的非负整数,叫做描述符,它在后续对此文间的所有操作中标识这个文件。内核记录有关这个打开文件的所有信息。应用程序只需要记住这个描述符。
  2. Linux shell 创建的每个进程开始时都由三个打开的文件:标准输入、标准输出和标准错误
  3. 改变当前的文件位置。对于每个打开文件,内核保持着一个文件位置k,初始为0。即从文件开头起始的字节编偏移量。
  4. 读写文件一个读操作就时从文件复制n>0个字节到内存,从当前文件位置k开始,然后将k增加到k+n。当超过文件字节大小时,读操作会出发一个end-of-file的条件,应用程序能检测到这个条件。同理,写操作就时从内存复制n个字节到一个文件中。
  5. 关闭文件。当应用完成对文件的访问之后,它就通知内核关闭文件。作为响应,内核释放文件打开时创建的数据结构,并将这个描述父回复到可用的描述符池中。无论一个进程因为何种原因终止时,内核都会关闭所有打开的文件并释放他们的内存资源。

文件

每个Linux文件都有一个类型(type)来表明它在系统中的角色:

  1. 普通文件
  2. 目录(directory),包含一组链接文件,每个链接都将医生文件名映射到一个文件,这个文件可能时目录。每个目录至少含有两个条目:”.”是该目录自身的链接,以及“..”是到目录层次结构中父目录的链接。下图是window下,使用vim命令打开的一个目录
  3. 嵌套字(socket)用来与另一个进程进行跨网络通信的文件
    其他文件类型包含命名通道(named pipe)、符号链接(symbol link),以及字符和块设备(character and block device)。

在使用读、写文件的时候,使用read和write传送的字节比应用程序要求的要少,这些不足值(short count)不表示有错误,出现这样的情况原因有:

  1. 读时遇到EOF: 假设我们准备读一个文件,该文件从当前文件位置开始值含有20多个字节,而我们以50个字节的片段进行读取。这样返回不足值为20,此后read将通过返回不足值0来发出EOF信号。
  2. 从终端读取文本行。如果打开文件是与终端相关联的,那么每个read函数将一次传送一个文本行,返回的不足值等于文本行大小。
  3. 读和写网络套接字,如果打开的文件对应于网络套接子,那么内部缓冲约束和较长的网络延迟会引起read和write返回不足值。

如果想创建健壮Web服务器这样的网络应用,就必须通过反复调用read和write处理不足值,知道所需要的字节都传送完毕。

RIO 包健壮地读写

称为 Robust I/O,它会自动处理文件读写时的不足值。RIO提供了两类不同的函数

  1. 无缓冲的输入输出函数,直接在内存和文件之间传送数据,没有应用级缓冲。它们对将二进制数据读写到网络和从网络读写二进制数据尤其有用。
  2. 带缓冲的输入函数,这些函数允许你高效地从文件中读取文本和二进制数据,着些文件内容缓存在应用级缓冲区内,类似于为printf这样的标准I/O函数提供的缓冲区。

C语言定义了一组高级输入函数,称为标准I/O库,为程序员提供了Unix I/O的较高级别的替代。

网络I/O

在Internet 网中,客户端和服务器通过在连接上发送和接收字节流来通信。从连接一对进程的意义上而言,连接是点对点的。从数据可以同时双向流动的角度来说,它是全双工的。并且从由源进程发出的字节流最终被目的进程以它发出的顺序收到它的角度来说,它也是可靠的。

一个套接是连接的一个端点。每个套接字都有相应的套接字地址,是由一个Internet地址和一个16位的整数端口组成。当客户端发起一个请求时,客户端套接字中的端口时由内核自动分配的,称为临时端口。服务器套接字地址中的端口通常时某个知名端口,一个特定的服务与该端口进行关联。

相关文章

用的openwrt路由器,家里宽带申请了动态公网ip,为了方便把2...
#!/bin/bashcommand1&command2&wait从Shell脚本并行...
1.先查出MAMP下面集成的PHP版本cd/Applications/MAMP/bin/ph...
1、先输入locale-a,查看一下现在已安装的语言2、若不存在如...
BashPerlTclsyntaxdiff1.进制数表示Languagebinaryoctalhexa...
正常安装了k8s后,使用kubect工具后接的命令不能直接tab补全...