Unix 5种 I/O模型
I/O操作分为两步:(1)先将数据从 存储介质 (磁盘或者网络等)拷贝到 内核缓冲区,此时称为数据准备好,可以被用户读取。 (2)由用户应用程序拷贝内核缓冲区数据 到用户缓冲区。 1.阻塞I/O模型函数 recfrom 视为系统调用。 不论该函数如何实现, 都会有 从应用进程中运行 到 内核中运行的 切换, 一段时间以后 还会有 一个返回 到应用进程的切换。 应用程序 调用一个I/O 函数, 导致应用程序阻塞 并等待数据准备就绪。 如果数据没有准备好 就一直等待。 如果数据准备好了, 则从内核拷贝到用户空间拷贝数据,IO函数 返回成功指示。
进程调用 recvfrom 此系统调用 直到 数据报到达 且被复制到应用进程的缓冲区中 或发生 错误才返回, 常见的错误如 系统调用被信号中断。 进程在调用 recvfrom开始 到它 返回的 整段时间内是阻塞的, 该函数成功返回后,应用程序 开始处理 数据报。 2.非阻塞I/O模型 (数据就绪之前 一直轮询)非阻塞接口 告诉内核 ,当所请求的IO未完成时,返回一个错误,而不是将进程睡眠。 因此,IO操作函数将不断的测试,数据是否已经准备好了。
前三次调用 recvfrom 函数 都无数据返回, 内核返回一个 EWOULDBLOCK错误。 第四次调用recvfrom时,数据报已准备好,被拷贝到应用缓冲区, recvfrom返回成功指示, 接着处理数据。 当一个应用进程 非阻塞 循环调用 recvfrom时,称为轮询 polling 。 3.I/O 复用模型 (select poll)I/O 复用模型会用到 select 或者 poll 函数, 这两个函数也会使进程阻塞, 但是和阻塞I/O不同的是,这两个函数 可以 同时阻塞多个I/O操作。
只要有数据就绪, select 调用返回, 应用程序调用 recvfrom 将数据 从内核区拷贝至 用户区。 优势在于,每次select阻塞 结束返回后, 可以获得多个准备就绪的套接字(即一个select 可以对多个套接字进行管理,类似于同时监控多个套接字事件是否就绪)。 和阻塞IO相比较, select I/O 复用模型相当于提前阻塞了。 等到有数据到来时,再调用revcfrom函数 就不会因为要等数据而发生阻塞。 4.信号驱动 I/O模型让内核在数据就绪时 用信号SIGIO通知应用程序。
5.异步I/O让内核启动操作, 在整个操作完成后(将数据 从内核拷贝到 用户空间) 通知应用程序。 调用aio_read函数, 告诉内核描述字, 缓冲区指针,缓冲区大小, 文件偏移以及通知的方式,然后立即返回。 当内核将数据拷贝到缓冲区后,在通知 应用程序。
五种IO 模型对比:
文中涉及的 unix 函数:The recvfrom() and recvmsg() 调用用于从套接字接收消息,并且可以被用于接收套接字上的数据是否是面向连接的。 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |