1. 混淆的IO概念
IO 是输入和输出的缩写。广义上讲,计算机周围有很多输入输出功能:鼠标、键盘、扫描仪等。我们今天要讨论的是计算机中的输入输出操作,主要作用于内存、网卡、硬盘等硬件设备。
说到IO模型,大多数人脑子里肯定有很多困惑,“阻塞”、“非阻塞”、“同步”、“异步”到底有什么区别?很多同学分不清其中的区别,有的试图搜索相关资料探个究竟,却淹没在茫茫的概念之中。
这里我尝试简单解释一下为什么会出现这种现象,其中一个重要原因是大家看到的资料对概念的解释角度不同,有的是从底层内核的角度,有的则直接在Java层面或者Netty框架层面给大家介绍API,给大家造成了一定程度的困惑。
那么在开始之前,我先说一下这篇文章的视角,我们会从最底层的内核层面来讲解IO。因为不管怎么变,本质还是不变的,只有理解了底层的原理,无论语言层面多么花哨,我们才能在一切变化面前保持不变。
文章相关视频讲解:C/C++Linux服务器开发高级架构学习视频点击:C/C++Linux服务器开发高级架构/Linux后台架构师-学习视频 90分钟掌握底层网络IO模型,你必须了解的10种模型 epoll原理解析及reactor模型应用 linux epoll网络编程细节处理 2.用户空间与内核空间
为了帮助大家理解复杂的IO和零拷贝相关技术,我们还是得花些时间复习一下操作系统相关的知识。这一节我们会重点讲解用户空间和内核空间,以此为基础后面才能更好地讲解复用和零拷贝。
硬件
包括我们熟悉的、与IO相关的CPU、内存、磁盘和网卡硬件;
内核空间
当计算机开机时,首先会运行内核程序,内核程序占用一个私有空间,称为内核空间,这个空间可以支持对CPU所有指令集(ring0-ring3)以及所有内存空间、IO和硬件设备的访问。
用户空间
每个普通用户进程都有独立的用户空间,只能访问受限制的资源(CPU“保护模式”),也就是说用户空间不能直接操作内存、网卡、磁盘等硬件;
正如上面所说,我们可能会有疑问,用户空间进程如果要访问或者操作磁盘、网卡的话,该怎么办呢?
为此,操作系统在内核开辟了一个唯一且合法的调用入口“系统调用接口”,也就是我们常说的系统调用。系统调用给上层用户提供了一组可以操作底层硬件的API。这样,用户进程就可以通过系统调用访问操作系统内核,进而间接完成对底层硬件的操作。这个访问过程也就是从用户态到内核态的切换。常见的系统调用有很多,比如:内存映射 mmap()、文件操作类 open()、IO读写 read()、write() 等。
点击获取C/C++ Linux后端网络开发底层原理学习资料,内容和知识点涵盖Linux、Nginx、ZeroMQ、MySQL、Redis、线程池、MongoDB、ZK、Linux内核、CDN、P2P、epoll、Docker、TCP/IP、协程、DPDK等。