《UNIX网络编程》中五种I/O方式总结和对比

UNIX提供了五种不同的I/O模型:

  • 阻塞式I/O模型

  • 非阻塞式I/O模型

  • I/O复用模型

  • 信号驱动式I/O模型

  • 异步I/O模型

阻塞式I/O模型

阻塞式I/O模型是最基本的I/O模型。在默认情况下,所有套接字都是阻塞的,以数据报套接字为例:

《UNIX网络编程》中五种I/O方式总结和对比_第1张图片

当系统调用recvfrom系统调用函数时,当内核socket缓冲区中这个套接字数据报准备好时,将数据从内核缓冲区复制到用户空间,复制完成的时函数返回成功。当发生错误时recvfrom会返回出错。recvfrom只有接收或者出错时才会返回,其余时间都是阻塞的。

非阻塞式I/O模型

当套接字被设置成非阻塞时,是在向内核发通知:在recvfrom没有完成时不要在这个函数阻塞这个进程。

《UNIX网络编程》中五种I/O方式总结和对比_第2张图片

在例子中,recvfrom函数采用了轮询的方式来获得内核中准备好的数据报,每一次调用recvfrom,都会查看操作是否就绪,如果数据没有就绪,内核会返回一个EWOULDBLOCK错误,这个错误并不是致命的,而是可以处理的,数据就绪后recvfrom成功返回。这种经常调用系统调用的函数会使得程序不断在用户态和内核态之间转换,会耗费大量的CPU时间,拖慢整个系统。

I/O复用模型

I/O复用模型经常是调用select或者poll来实现,程序只会阻塞在这两个函数的某一个条件上,而不是阻塞在I/O系统调用上。

《UNIX网络编程》中五种I/O方式总结和对比_第3张图片

我们阻塞于select调用,当可读条件返回的时,我们再调用recvfrom获取准备好的数据报。

信号驱动式I/O模型

我们利用UNIX的信号机制,当内核在描述符就绪时发生给我们一个SIGIO信号,我们捕获这个信号再进行处理。

《UNIX网络编程》中五种I/O方式总结和对比_第4张图片

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

异步I/O模型

异步操作的原理简单来说,就是我们给内核定下某个操作,让内核在完成整个操作的时候通知我们。

《UNIX网络编程》中五种I/O方式总结和对比_第5张图片

此处调用的是aio_read函数,它给内核传递文件描述符、缓冲区指针、缓冲区大小和文件偏移(与lseek相似),并高速内核当完成整个操作的时候如何通知我们。该系统调用立即返回,不会阻塞进程。和上面信号驱动式I/O模型的区别是:信号驱动式I/O当满足操作条件的时候由内核告诉我们可以执行,而异步I/O则是由内核告诉我们操作何时完成。

五种I/O方式横向比较

《UNIX网络编程》中五种I/O方式总结和对比_第6张图片

此中,前四种模型都是 同步 I/O模型,recvfrom真正进行数据复制的时候会阻塞进程,而异步I/O型不会阻塞进程。

你可能感兴趣的:(UNIX/Linux,网络协议与网络编程,网络编程,unix,socket,io)