zoukankan      html  css  js  c++  java
  • 大话 Select、Poll、Epoll

    提到select、poll、epoll相信大家都耳熟能详了,三个都是IO多路复用的机制,可以监视多个描述符的读/写等事件,一旦某个描述符就绪(一般是读或者写事件发生了),就能够将发生的事件通知给关心的应用程序去处理该事件。本质上,select、poll、epoll本质上都是同步I/O,相信大家都读过Richard Stevens的经典书籍UNP(UNIX:registered: Network Programming),书中给出了5种IO模型:

    [1] blocking IO - 阻塞IO [2] nonblocking IO - 非阻塞IO [3] IO multiplexing - IO多路复用 [4] signal driven IO - 信号驱动IO [5] asynchronous IO - 异步IO

    其中前面4种IO都可以归类为synchronous IO - 同步IO,在介绍select、poll、epoll之前,首先介绍一下这几种IO模型,signal driven IO平时用的比较少,这里就不介绍了。

    1. IO - 同步、异步、阻塞、非阻塞

    下面以network IO中的read读操作为切入点,来讲述同步(synchronous) IO和异步(asynchronous) IO、阻塞(blocking) IO和非阻塞(non-blocking)IO的异同。一般情况下,一次网络IO读操作会涉及两个系统对象:(1) 用户进程(线程)Process;(2)内核对象kernel,两个处理阶段:

    [1] Waiting for the data to be ready - 等待数据准备好
    [2] Copying the data from the kernel to the process - 将数据从内核空间的buffer拷贝到用户空间进程的buffer
    

    IO模型的异同点就是区分在这两个系统对象、两个处理阶段的不同上。

    1.1 同步IO 之 Blocking IO

    如上图所示,用户进程process在Blocking IO读recvfrom操作的两个阶段都是等待的。在数据没准备好的时候,process原地等待kernel准备数据。kernel准备好数据后,process继续等待kernel将数据copy到自己的buffer。在kernel完成数据的copy后process才会从recvfrom系统调用中返回。

    1.2 同步IO 之 NonBlocking IO

    从图中可以看出,process在NonBlocking IO读recvfrom操作的第一个阶段是不会block等待的,如果kernel数据还没准备好,那么recvfrom会立刻返回一个EWOULDBLOCK错误。当kernel准备好数据后,进入处理的第二阶段的时候,process会等待kernel将数据copy到自己的buffer,在kernel完成数据的copy后process才会从recvfrom系统调用中返回。

    1.3 同步IO 之 IO multiplexing

    IO多路复用,就是我们熟知的select、poll、epoll模型。从图上可见,在IO多路复用的时候,process在两个处理阶段都是block住等待的。初看好像IO多路复用没什么用,其实select、poll、epoll的优势在于可以以较少的代价来同时监听处理多个IO。

    1.4 异步IO

    从上图看出,异步IO要求process在recvfrom操作的两个处理阶段上都不能等待,也就是process调用recvfrom后立刻返回,kernel自行去准备好数据并将数据从kernel的buffer中copy到process的buffer在通知process读操作完成了,然后process在去处理。遗憾的是,linux的网络IO中是不存在异步IO的,linux的网络IO处理的第二阶段总是阻塞等待数据copy完成的。真正意义上的网络异步IO是Windows下的IOCP(IO完成端口)模型。

    很多时候,我们比较容易混淆non-blocking IO和asynchronous IO,认为是一样的。但是通过上图,几种IO模型的比较,会发现non-blocking IO和asynchronous IO的区别还是很明显的,non-blocking IO仅仅要求处理的第一阶段不block即可,而asynchronous IO要求两个阶段都不能block住。

    ------------------越是喧嚣的世界,越需要宁静的思考------------------ 合抱之木,生于毫末;九层之台,起于垒土;千里之行,始于足下。 积土成山,风雨兴焉;积水成渊,蛟龙生焉;积善成德,而神明自得,圣心备焉。故不积跬步,无以至千里;不积小流,无以成江海。骐骥一跃,不能十步;驽马十驾,功在不舍。锲而舍之,朽木不折;锲而不舍,金石可镂。蚓无爪牙之利,筋骨之强,上食埃土,下饮黄泉,用心一也。蟹六跪而二螯,非蛇鳝之穴无可寄托者,用心躁也。
  • 相关阅读:
    MCU开发之I2C通信
    hibernate特殊的映射
    Hibernate使用
    css设置让a标签充满整个li
    margin
    border属性
    列表
    链接样式
    相机内参外参
    tmux
  • 原文地址:https://www.cnblogs.com/feng9exe/p/15235447.html
Copyright © 2011-2022 走看看