I/O模型总结

  • 5大I/O模型介绍
    • 阻塞式I/O模型
    • 非阻塞式I/O模型
    • I/O复用模型
    • 异步I/O
阻塞式I/O

未完成输入或者输出,导致程序阻塞,直到输入输出工作完成为止。在网络编程中,进程读取套接字关联的内核缓冲区数据,当缓冲区为空时,不会再进行系统调用,而是被投入到睡眠状态,但是等到内核缓冲区有数据后,进程又开始读取数据;当从进程往套接字缓冲区写数据时,缓冲区中没有多余空间来容纳数据,进程就被投入睡眠,等待用户读取缓冲区中的数据空出空间。然后唤醒进程进行写操作;当要求读取一定长度的数据时,而每次缓冲区中数据的长度不符合要求长度,进程也会陷入等待,直到数据满足读取期望为止。

在这里插入图片描述

以上是出自书上的一幅图,没有包含写数据的哪一部分。

非阻塞I/O

相对于阻塞I/O,非阻塞I/O是就算你套接字关联内核空间没有数据可读,他还是要不停地进行系统调用,判断是否有数据可读,当有数据时就会将内核数据复制到进程中,作相应处理,写数据是同样的道理。所以不难看出,非阻塞相比于阻塞多了频繁的系统调用,所以会消耗系统资源。

在这里插入图片描述

正如上图所示,当不满足读写条件时,进程会循环调用recvfrom检测内核是否有数据可读。
注意:其中EWOULDBLOCK是一种慢系统调用中断错误信号。什么是慢系统调用?就是在程序中调用一些可能永远不会返回的系统函数,如accept。所以进程会产生一些中断信号,EWOULDBLOCK为其中一种,还有一个常用到的EINTR。

I/O复用模型

I/O复用就是通过调用系统中的select和poll函数,当套接字所关联的缓冲区中没有数据可读时,进程阻塞于select或者poll这段。感觉和阻塞式I/O并没有多大区别,惟一的区别就是select可以等带多个套接字就绪。

信号驱动式I/O

当描述符处于就绪状态时,内核通过信号SIGIO来通知进程,可以复制数据。

异步I/O

告诉内核启动某个操作,并让内核在该操作(包括内核将数据cp到缓冲区)执行完成后通知进程。这和信号驱动式I/O的主要区别是前者的从内核缓冲区cp数据是用户进程完成的,而后者是内核完成的。

猜你喜欢

转载自blog.csdn.net/qq_41681241/article/details/85217564