linux五中IO模型

在理解IO模型之前,先说明几个问题
(1)为什么读取文件需要用户进程通过系统调用让内核完成(可能问题有点low,但确实困扰我很久啊~~)
建议先看一下这篇文章https://www.cnblogs.com/sparkdev/p/8410350.html,讲的是linux进程的用户态和内核态的东西

什么是用户态和内核态?为什么要区分内核态和用户态呢?
用户态就是进程运行在用户空间,内核态就是进程运行在内核空间。
“在CPU的所有指令中,有些指令是非常危险的,如果错用,将导致系统崩溃,如果允许所有的程序都可以使用这些指令,那么系统崩溃的概率就大大增加”。所以,为了安全性和稳定性考虑,linux就区分了内核态和用户态,对于那些比较敏感的操作,就只能让cpu运行在内核态执行。

那么什么样的操作只能运行在内核态呢?
用户态:只能受限的访问内存,无法访问外围设备。
内核态:可以访问内存所有数据
所以,一些对外围设备的访问操作比如硬盘、网卡都只能运行在内核态,此外进程调度、TCP/IP协议栈等也只能工作在内核态。
(2)文件描述符(fd)
参见(https://baike.baidu.com/item/%E6%96%87%E4%BB%B6%E6%8F%8F%E8%BF%B0%E7%AC%A6
文件描述符是一个负整数,实际上,他是一个索引值,指向内核为每一个进程所维护的该进程打开文件的记录表,当程序打开一个现有文件或者创建一个新文件时,内核向进程返回一个文件描述符。当我们的进程想要对文件进行读写的时候,就会传递这个文件描述符给内核空间,内核就会根据不同类型的IO对相应的数据进行操作返回。
好了,接下来就要讲解内核根据文件描述符对数据进行操作的方式–IO模型了。

1、进程读取数据过程综述

用户进程如果想要从外围设备(这里以socket为例)读取数据,需要首先经过内核,那这里就涉及到和内核的通信问题了(通信同步异步、阻塞非阻塞见我的这篇博客:https://blog.csdn.net/u014473112/article/details/80793274),linux中这个通信过程具体有五种方式(信号驱动不常用,不讲):

  • 阻塞IO
  • 非阻塞IO
  • IO多路复用
  • 信号驱动IO
  • 异步IO

2、各个IO模型介绍

(1)阻塞IO
这里写图片描述
    用户进程想要读取数据了,于是就通过执行recvfrom来进行一次系统调用(system call),于是进入内核态,内核态的进程刚开始要准备数据,准备好了之后呢又要执行复制到用户空间的操作,直到复制完成返回,整个过程,用户进程都处于阻塞状态,这是相当低效的。

(2)非阻塞IO
这里写图片描述
    用户进程想要读取数据了,于是就通过执行recvfrom来进行一次系统调用,进入内核态,内核态如果数据没有准备好就直接返回一个没有准备好的标志,我们这边的用户进程也没有闲着,就去干别的事了,但是还是会定时轮询系统调用查看数据是否准备好

(3)IO多路复用
这里写图片描述
    对于前面两种方式,一个进程就只能处理一个连接的读或者写事件,在现今服务器要处理大量连接的情况下,这无疑是很大的瓶颈,那多路复用就派上用场了。
    当有很多连接要进行读或者写的时候,用户进程通过将fd_set传递给一个函数,比如select函数,select函数触发了系统调用,进入内核态,内核如果看到有某个fd对应的数据准备好了,就会返回这个fd,select在接收这个返回的过程中一直是阻塞的,当接收到这个返回之后就在用户进程的fdset查找对应fd,然后再执行系统调用,这次系统调用不再是让内核返回就绪文件描述符了,而是让内核读取数据返回,当然这个过程进程也是阻塞的。
    在select等待就绪fd的过程中,可以认为是使用了同步阻塞模式,在获取到数据可读的fd之后,再次系统调用是阻塞读取的。其实从select等待就绪fd的过程里面看,Io多路复用相对阻塞IO还有点相似,也是在数据到来之前阻塞,但是呢,IO多路复用的优势就是可以处理多个连接,这对于服务器来说是很重要的。

(4)异步IO
这里写图片描述
    异步IO,顾名思义,内核在接收到用户进程的系统调用之后,内核会直接返回,但是返回的不是读取的数据,这张图使用的是通知的方式执行异步,当内核把数据复制到用户空间的操作完成选择了主动通知用户进程,不是用状态的方式,这也是比较常用的方式

    其实,看了很多文章,有对”非阻塞IO”总是冠以”异步非阻塞”、 “同步非阻塞”的名头,对“异步IO”总是冠以”异步非阻塞“、”异步阻塞“的名头,自己刚开始觉得说的有道理,但是后来一想,我觉得”非阻塞IO”和同步异步没有关系,两种模式都可以实现,“异步IO”和阻塞非阻塞也没有关系,两种也可以实现,只是相对来说,异步非阻塞实现的比较常见罢了。

猜你喜欢

转载自blog.csdn.net/u014473112/article/details/80795205