IO模型学习笔记

IO模型学习笔记

Unix下的5种I/O模型

  • 阻塞式I/O;
  • 非阻塞式I/O;
  • I/O复用(select 和 poll);
  • 信号驱动式I/O(SIGIO);
  • 异步I/O(POSIX的aio_系列函数)。

阻塞式I/O模型

进程调用recvfrom, 其系统调用直到数据包到达且被复制到应用进程的缓冲区中或者发生错误才返回。

最常见的错误是系统调用被信号中断。进程在从调用recvfrom开始到它返回的整段时间内是被阻塞的。recvfrom成功返回后,应用进程开始处理数据报。

优点是能够及时返回数据,无延迟。

缺点是对用户来说处于等待就要付出性能的代价。

非阻塞式I/O模型

进程把一个套接字设置成非阻塞是在通知内核:当所请求的I/O操作非得把本进程投入睡眠才能完成时,不要把本进程投入睡眠,而是返回一个错误。

当调用recvfrom时没有数据可返回,内核转而立即返回一个EWOULDBLOCK错误。当调用recvfrom时已有一个数据报准备好,它被复制到应用进程缓冲区,于是recvfrom成功返回。

当一个应用进程像这样对一个非阻塞描述符循环调用recvfrom时,这叫做轮询(polling)。

优点是能够在等待任务完成的时间里做其它的任务。

缺点是往往耗费大量的CPU时间,响应延迟增大了。

I/O复用模型

进程阻塞于select调用,等待数据报套接字变为可读。当select返回套接字可读这一条件时,调用recvfrom把所读数据报复制到应用进程缓冲区。

IO复用同非阻塞IO本质一样,不过利用了新的select系统调用,由内核来负责本来是请求进程该做的轮询操作。看似比非阻塞IO还多了一个系统调用开销,不过因为可以支持多路IO,才算提高了效率。

select/epoll的优势并不是对于单个连接能处理得更快,而是在于能处理更多的连接。

信号驱动式I/O模型

可以用信号让内核在描述符就绪时发送SIGIO信号通知我们。

首先开启套接字的信号驱动I/O功能,并通过sigaction系统调用安装一个信号处理。该系统调用立即返回,进程继续工作。当数据报准备好读取时,内核为进程产生一个SIGIO信号。我们随后既可以在信号处理函数中调用recvfrom读取数据报,并通知主循环数据已准备好待处理,也可以立即通知主循环,让它读取数据报。

优势是等待数据报到达期间进程不被阻塞。主循环可以继续执行,只要等待来自信号处理函数的通知。

异步I/O模型

告知内核启动某个操作,并让内核在整个操作(包括将数据从内核复制到我们自己的缓冲区)完成后通知我们。

异步I/O模型 跟 信号驱动式I/O模型 的区别:信号驱动式I/O是由内核通知我们何时可以启动一个I/O操作,而异步I/O模型是由内核通知我们I/O操作何时完成。

我们调用aio_read函数(POSIX异步I/O函数以aio_或lio_开头),给内核传递描述符、缓冲区指针、缓冲区大小(与read相同的三个参数)和文件偏移(与lseek类似),并告诉内核当整个操作完成时如何通知我们。

各种I/O模型的比较

前4种模型的主要区别在于第一阶段,因为第二阶段是一样的:在数据从内核复制到调用者的缓冲区期间,进程阻塞于recvfrom调用。

同步I/O和异步I/O对比

阻塞式I/O模型、非阻塞式I/O模型、I/O复用模型和信号驱动式I/O模型都是同步I/O模型。

原文地址:https://www.cnblogs.com/linyihan/p/5566768.html