0%

IO模型简介

大致有下面五种IO模型:

阻塞IO模型,非阻塞IO模型,IO复用模型,信号驱动IO模型,异步IO模型。

阻塞IO模型

读数据,发现没有数据,线程就一直等待直到有数据读取。

非阻塞IO模型

读数据,发现没有数据,线程不等待直接返回读错误码。由于不知道什么时候会有数据所以这种非阻塞IO模型需要调用方不断检查是否有数据。

fd默认是阻塞IO访问,可以使用fcntl函数设置为非阻塞IO:

1
status = fcntl(socketFD, F_SETFL, O_NONBLOCK);

IO复用模型

对非阻塞IO模型的一种改进,因为非阻塞IO模型需要不断检查是否有数据可读。假如有100个fd要读,那么就需要100个线程各自在不断的检查是否有数据可读,这显然浪费了大量的CPU和内存。

事实上,我们可以用一条线程去轮询fd集合,当某个fd有数据可读时就返回该fd并通知应用程序读。系统内核提供了select内核函数,select函数会帮我们做上述事情,当线程调用select函数后会阻塞在select函数,当有数据可读时select函数会返回该fd,于是我们再开线程读取数据。

信号驱动IO模型

信号驱动IO模型是对上述模型中轮询策略的一种改进,因为轮询的效率是很低的,绝大多数时候是没有数据可读的,因此轮询做了大量无用功。

我们可以向系统内核注册一个信号,系统内核发现有数据可读时再发送该信号通知我们,于是我们才去读数据。

异步IO模型

异步IO模型是对信号驱动IO模型进一步改进。因为信号驱动IO模型只是告诉了我们读数据的时机,我们还是需要调用recvfrom函数去读把数据从内核空间复制到用户空间。

事实上,我们可以把信号驱动IO模型的两步并做一步,向系统内核发起一个read请求,随即返回。系统内核接收请求,当发现有数据可读时直接帮我们把数据从内核空间复制到用户空间并通知应用。

这几种模型体现了技术的不断发展,体现了人们对性能的不断追求。技术不是一蹴而就的而是从一个粗糙的东西不断迭代最终才变成一个精细的东西的。所以完美的事物是不存在的,你不必完美。

参考

100%弄明白5种IO模型

socket阻塞与非阻塞,同步与异步、I/O模型 主要看那几幅图。

网络编程必备知识:图解Socket核心内幕以及五大IO模型 | 阻塞IO,非阻塞IO,IO复用,信号驱动式IO,异步IO 感觉很吊的样子

觉得文章有帮助可以打赏一下哦!