zoukankan      html  css  js  c++  java
  • 关于IO多路复用的简单整理

    并发: 一段时间内,有几个程序在同一个cpu上运行,但是任意时刻只有一个程序在一个cpu上运行
    并行: 任意时刻有多个程序同时运行在多个cpu上

    同步、异步,与阻塞、非阻塞不相关

    函数或方法被调用的时候,调用者是否得到最终结果
    同步: 直接得到最终结果的,就是同步调用。同步就是一直要执行到返回最终结果
    异步: 不直接得到最终结果的,就是异步调用。异步就是直接返回了,但是返回的不是最终结果

    函数或方法被调用的时候,是否立刻返回,调用者是否还能干其他事
    阻塞: 不立即返回就是阻塞调用
    非阻塞: 立即返回就是非阻塞调用

    C10K问题,是在1999年被提出来的一个技术挑战
    如何在一颗1GHzCPU、2G内存、1gbps网络环境下,让单台服务器同时为1万个客户端提供ftp服务

    unix中的五种IO模型:

    • 阻塞式IO
    • 非阻塞式IO
    • IO多路复用(select、poll、epoll)
    • 信号驱动式IO
    • 异步IO(posix的aio_系列函数)

    IO过程分两个阶段
    1、数据准备阶段,数据到达后被复制到内核的缓冲区中
    2、进程从内核复制数据,将数据从内核空间复制到用户空间

    IO多路复用就是通过一种机制,一个进程或可以监视多个描述符,一旦某个描述符就绪(一般是读就绪或者写就绪),就通知程序进行相应的读写操作。
    但select、poll、epoll本质上都是同步IO,因为在就绪后它们都需要自己负责进行读写,这个读写过程是阻塞的。
    而异步IO无需自己负责进行读写,异步IO的实现会负责把数据从内核空间拷贝到用户空间。

    select几乎所有操作系统平台都支持,poll是对的select的升级。
    epoll,Linux系统内核2.6开始支持,对select和poll的增强,在监视的基础上,增加回调机制。BSD、Mac平台有kqueue,Windows有iocp。

    select

    select函数监视的文件描述符分三类,分别是writefds、readfds、和exceptfds。
    调用select()会阻塞,直到有描述符就绪、或者超时,函数才返回。
    当select函数返回后,可以通过遍历events来找到就绪的描述符。
    select几乎支持所有平台,其良好的跨平台支持也是它的一个优点。
    缺点在于单个进程能够监视的文件描述符的数量存在上限,在linux上一般为1024,可以通过修改修改这个限制,但是这样也可能会造成效率降低,不建议修改。

    poll

    select使用三个位图来表示三个fdset,不同于select,poll使用pollfd的一个指针实现。
    pollfd结构包含了要监视的event和发生了的event,不再使用select的'参数-值'传递方式。
    pollfd使用链表,没有最大数量限制,同select一样,poll返回后,需要遍历pollfd来获取就绪的描述符。

    select和poll都需要在返回后通过遍历来获取已经就绪的socket。
    实际上,同时连接的大量客户端在同一时刻可能只有很少的处于就绪状态,随着监视的描述符数量的增长,其效率也会线性下降。

    epoll

    epoll出现在内核2.6之后,是select和poll的增强版本。
    相对于select和poll来说,epoll更加灵活,没有描述符数量限制,增加了回调机制,使用事件通知,不需要遍历,效率很高。
    epoll使用一个文件描述符管理多个描述符,将用户关系的文件描述符的事件存放到内核的一个事件表中,这样,从内核空间到用户空间的copy只需一次。
    epoll的查询使用了红黑树数据结构,效率很高,不过红黑树本身很复杂。

    select/poll还要从内核空间复制数据到用户空间,而epoll通过内核空间和用户空间共享一块内存来减少复制。

    C10M问题
    如何利用8核心CPU、64G内存,在10gbps的网络上保持1000W并发连接。

    异步IO
    进程发起异步IO请求,立即返回。内核完成IO的两个阶段之后,即数据从内核空间复制到用户空间之后,内核才给进程发一个信号。
    Linux的aio的系统调用,内核从版本2.6开始支持。

    参考:
    https://docs.python.org/3/library/asyncore.html
    https://blog.csdn.net/twostyle/article/details/73967648
    https://www.cnblogs.com/nulige/p/6297829.html

  • 相关阅读:
    JavaScript中的闭包(closure)
    JavaScript中的继承与原型链
    一个PHP操作大变量的例子
    深入PHP内核之参数
    django创建一个简单的web站点
    django通过添加session来保存公共变量
    第一次登录mysql,使用任何命令都报错ERROR 1820 (HY000): You must reset your password using ALTER USER statement before executing this statement.
    django搭建的站点,通过localhost能访问,但是通过ip不能访问
    django models实际操作中遇到的一些问题
    python3 django连接mysql,同步表结构
  • 原文地址:https://www.cnblogs.com/keithtt/p/12981187.html
Copyright © 2011-2022 走看看