• IO多路复用机制-以及相关基础



    > **如果你想深入了解Linux中IO多路复用,则你需要知道的基础以及内部的一些机制就在这里**


    ## 一、基础概念
    1、Linux系统一切皆文件,如socket、pid等
    - 如查看某个进程打开的文件: ll /proc/[进程ID]/fd
    - 文件描述符限制:系统、用户
    - 系统限制设置的是:系统中所有用户的文件描述符总的最大值
    - 用户限制是:用户所能打开的最大文件描述符的大小
    - 用户限制设置(查看设置-ulimit -n): vim /etc/security/limits.con
    ~~~
    * - nofile 65535
    * soft nofile 65536
    * hard nofile 131072
    * soft nproc 2048
    * hard nproc 409
    ~~~
    - 查看系统文件描述符限制:sysctl -a| grep fs.file-max


    2、用户空间、内核空间

    - 内核:操作系统的核心就是内核,它可以访问受保护的内存空间,也可以访问硬件设备
    - 为了保证内核安全-用户进程不能直接访问内核,操作系统将内存划分为内核空间(内核使用)、用户空间(用户进程使用),
    - 用户态:进程运行在用户空间,则为用户态
    - 内核态:进程运行在内核空间,则为内核态
    - 说明:所有的系统资源管理都是内核空间中完成,如磁盘读写,分配回收内存,网络读写数据,我们的应用是通过内核提供的接口进行来完成的。

    3、 文件描述符
    - 对网络和文件的读写都会返回文件描述符(一切皆文件,统一了操作的API)

    4、文件缓存(pageCache)
    - 解决内存和硬盘性能差异的问题
    - 文件读取,先把文件拷贝到内核Page Cache中,然后拷贝到用户态内存
    - 写文件,先把内容写入到内核的Page Cache中,然后线程就返回,Page中的数据会被内核线程pbflush异步写入到硬盘上

    5、磁盘IO种类
    - 标准访问:用户读写-用户空间-内核空间(PageCache)-磁盘(写入磁盘时间取决于系统)
    - 直接IO(跳过内核Page缓存,用户自己缓存):用户读写-用户空间-用户自己缓存-磁盘
    - 内存映射-mmap:把用户的内存和文件进行关联,操作内存就是操作文件(个人理解,以后在详细学习)
    - 零拷贝-sendfile:磁盘->内核buffer->socketbuffer(这个不保存数据,只保存数据的内存地址)-> 网卡-> 网络传输流程,正常的数据流转流程为:内核缓存->用户内存->socketbuffer-> 网卡,那零拷贝相比减少了用户内存和socketbuffer两个流程

    6、数据在各阶段延迟说明 - Latency Numbers Matter
    https://www.dazhuanlan.com/2019/12/11/5df09ea27c7bc/

    - 打开一个网站 几秒
    - 在数据库中查询一条记录-有索引十几毫秒
    - 机械硬盘寻址定位- 4毫秒
    - 从机械磁盘顺序读取1M数据- 2毫秒
    - 从SSD磁盘顺序读取1MB数据 - 0.3毫秒
    - 从远程Redis读取一条数据- 0.5毫秒
    - 从内存中读取1MB的数据- 十几微妙
    - Java程序本地方法调用- 几微妙
    - 网络传输2K数据 - 1微妙


    7、 网络IO缓存(在对网络进行读写的时候,都会经过一层缓存),socket(本质上是流,也是文件)
    8、网络IO过程中,数据读取分为两个阶段
    - 数据准备阶段:等待socket接收数据,并从socket读取数据,然后写入内核空间的过程
    - 数据拷贝阶段:数据从内核空间拷贝到用户空间的过程

    9、进程切换(使进程阻塞)

    10、Linux 的IO模型(主要以下面几个常用的学习)-纯个人理解
    - 同步阻塞:一个客户端访问到服务端,服务端启动一个线程等待客户端数据写入,服务端的线程是阻塞的(**不能做任何事情**),直到超时或者人为停止
    - 同步非阻塞:一个客户端访问到服务端,服务端启动一个线程等待客户端数据写入,服务端线程是非阻塞的(**等待过程中可以做其他事情**,但每隔一段时间要查询是否有数据进行处理),这个相对于同步阻塞来说,服务端线程可以做其他事情,但是依然需要大量线程来等待处理客户端请求
    - IO多路复用(同步阻塞的升级,数据拷贝过程是阻塞的):很多客户端访问到服务端,服务端仅启动**一个线程来监控多个客户端数据写入**,一旦有数据写入则服务端启动新线程处理,相比同步非阻塞减少了创建线程的数量,**多路复用**指的是复用一个线程来监控多个socket的写入


    11、在Linux中IO多路复用机制区别 select poll epoll

    - select :底层结构为数组,存储的文件描述符大小有限制,并且监控socket采用的是不断扫描整个数组,当数组比较大的时候,效率低下
    - poll :底层结构为连表,监控方式同select
    - epoll :基于事件通知机制,当某个socket有事件的时候,会调用callback来通知那个文件描述符活跃,然后通知服务端启动线程处理,减少了循环扫描对于资源的消耗

    12、参考:

    > - https://www.cnblogs.com/sunsky303/p/8962628.html
    > - https://www.jianshu.com/p/486b0965c296

  • 相关阅读:
    DirectFB、Layer、Window、Surface之间关系
    DirectFB的架构介绍
    Qt 学习之路 2(55):数据库操作
    MessageBox函数第一个参数hwnd的作用
    读取Properties文件以及中文乱码问题
    Maven项目读取resources下文件的路径问题(getClassLoader的作用)
    IDEA中Git更新合并代码后,本地修改丢失
    Cuba项目配置IDEA,如何dubug
    画删除线的方法,如何找替代方法,Deprecated注释
    Navicat的使用技巧
  • 原文地址:https://www.cnblogs.com/lean-blog/p/13559556.html
Copyright © 2020-2023  润新知