欢迎来到天天文库
浏览记录
ID:37315313
大小:246.50 KB
页数:7页
时间:2019-05-21
《UNIX系统的IO模型》由会员上传分享,免费在线阅读,更多相关内容在行业资料-天天文库。
1、UNIX系统的IO模型其实并非原创,只是摘录了Stevens的大作《UNIX网络编程》,写下来,一、加深理解和记忆;二、书是借的,记录一下备忘。感谢臻,借我此书一阅,受益匪浅。 6.2I/O模型阻塞式I/O;非阻塞式I/O;I/O复用;信号驱动式I/O;异步I/O;一个输入操作通常包括两个不同的阶段:1) 等待数据准备好;2) 从内核向进程复制数据;对于一个套接字上的输入操作,第一步通常涉及等待数据从网络中到达。当所等待分组到达时,它被复制到内核中的某个缓冲区。第二步就是把数据从内核缓冲区复制到应用进程缓冲区。6.2.1 阻塞式I/O模型最流行的I/O模
2、型是阻塞式I/O(blockingI/O)模型,默认情况下,所有套接字都是阻塞的。以数据报套接字作为例子,我们有如图6-1所示的情形。 图6-1 阻塞式I/O模型在图6-1中,进程调用recvfrom,其系统调用直到数据报到达且被复制到应用进程的缓冲区中或者发生错误才返回。我们说进程在从调用recvfrom开始到它返回的整段时间内是被阻塞的。recvfrom成功返回后,应用进程开始处理数据报。6.2.2 非阻塞式I/O模型进程把一个套接字设置成非阻塞是在通知内核:当所请求的I/O操作非得把本进程投入睡眠才能完成时,不要把本进程投入睡眠,而是返回一个错误。
3、非阻塞式I/O(notblockingI/O)模型如图6-2所示: 图6-2 非阻塞式I/O模型前三次调用recvfrom时没有数据可返回,因此内核转而立即返回一个EWOULDBLOCK错误。第四次调用recvfrom时已有一个数据报准备好,它被复制到应用进程缓冲区,于是recvfrom成功返回。我们接着处理数据。当一个应用进程像这样对一个非阻塞描述符循环调用recvfrom时,我们称之为轮询(polling)。应用进程只需轮询内核,以查看某个操作是否就绪。这么做往往耗费大量CPU时间。6.2.3I/O复用模型有了I/O复用(I/Omultiplexin
4、g),我们就可以调用select或poll,阻塞在这两个系统调用中的某一个上,而不是阻塞在真正的I/O系统调用上。图6-3概括展示了I/O复用模型。图6-3I/O复用模型我们阻塞于select调用,等待数据报套接字变为可读。当select返回套接字可读这一条件时,我们调用recvfrom把所读数据报复制到应用进程缓冲区。比较图6-3和图6-1,I/O复用并不显得有什么优势,事实上由于使用select需要两个而不是单个系统调用,I/O复用还稍有劣势。使用select的优势在于我们可以等待多个描述符就绪。与I/O复用密切相关的另一种I/O模型是在多线程中使用
5、阻塞式I/O(我们经常这么干)。这种模型与上述模型极为相似,但它并没有使用select阻塞在多个文件描述符上,而是使用多个线程(每个文件描述符一个线程),这样每个线程都可以自由的调用recvfrom之类的阻塞式I/O系统调用了。6.2.4 信号驱动式I/O模型我们也可以用信号,让内核在描述符就绪时发送SIGIO信号通知我们。我们称这种模型为信号驱动式I/O(signal-drivenI/O),图6-4是它的概要展示。 图6-4 信号驱动式I/O模型我们首先开启套接字的信号驱动式I/O功能,并通过sigaction系统调用安装一个信号处理函数。改系统调用将
6、立即返回,我们的进程继续工作,也就是说他没有被阻塞。当数据报准备好读取时,内核就为该进程产生一个SIGIO信号。我们随后就可以在信号处理函数中调用recvfrom读取数据报,并通知主循环数据已经准备好待处理,也可以立即通知主循环,让它读取数据报。无论如何处理SIGIO信号,这种模型的优势在于等待数据报到达期间进程不被阻塞。主循环可以继续执行,只要等到来自信号处理函数的通知:既可以是数据已准备好被处理,也可以是数据报已准备好被读取。6.2.5 异步I/O模型异步I/O(asynchronousI/O)由POSIX规范定义。演变成当前POSIX规范的各种早起
7、标准所定义的实时函数中存在的差异已经取得一致。一般地说,这些函数的工作机制是:告知内核启动某个操作,并让内核在整个操作(包括将数据从内核复制到我们自己的缓冲区)完成后通知我们。这种模型与前一节介绍的信号驱动模型的主要区别在于:信号驱动式I/O是由内核通知我们何时可以启动一个I/O操作,而异步I/O模型是由内核通知我们I/O操作何时完成。图6-5给出了一个例子。 图6-5 异步I/O模型我们调用aio_read函数(POSIX异步I/O函数以aio_或lio_开头),给内核传递描述符、缓冲区指针、缓冲区大小(与read相同的三个参数)和文件偏移(与lsee
8、k类似),并告诉内核当整个操作完成时如何通知我们。该系统调用立即返回,并且在等待
此文档下载收益归作者所有