zoukankan      html  css  js  c++  java
  • IO模型理解

    IO是操作系统中最重要的功能之一。说起IO,其实要从最开始的同步阻塞IO模型说起。

    首先理解下同步和非同步,阻塞和非阻塞。

    在Linux操作系统中,数据分为内核态和用户态。用户线程在用户态中运行,键盘,鼠标动作是由内核系统调用触发。

    同步,异步

    同步和非同步是从消息通信的角度来区分的。如果用户态中进程主动去到内核态中查询获取数据,这种就是同步机制。同步永远是进程主动去获取数据。如果数据可以通过通知的方法返回到用户进程,那么这种方式就是异步的。

    阻塞,非阻塞

    一个线程在运行期间,调用了其他方法,在该方法返回结果之前,如果此线程处于等待状态,那么这种就是阻塞的,如果方法立即返回一个结果(即使这个结果没有任何业务意义),调用该方法的线程转而去做了其他事情。那么这种方式就是非阻塞的。这个时候如果我们需要去获取该方法的真实返回结果,就需要采用同步的方式去获取(这里又是从消息的通知方式来说的)。

    三种常见的IO模型

    1. 阻塞式IO

    阻塞式IO最开始接触多线程编程时候入门的线程模型。一个线程在未得到另一个方法的返回值之前,需要一直挂起,知道方法返回数据后,才可以重新拿到时间片,继续运行。

     用户态进程进行系统调用后,内核态需要进行等待,知道数据准备好(比如键盘数据,远程调用等)后把数据从内核态复制到用户态后,调用进程才可以拿到数据继续运行。在这段时间内,调用进程不能做任何其他的事情,一直阻塞在那里。

    在具体的代码编写中,http服务器编式不能采用阻塞式IO编写的,因为当访问量增大后,会增加服务器的消耗,因为很多线程都是在等待客户端的连入,浪费资源。

    2.非阻塞式IO

    当进程进行系统调用后,内核系统会立即返回一个返回值。用户进程获取返回值后,并不能获取真实的处理结果。此时就需要以同步的模式主动去内核轮询处理结果,如果轮询有了结果,那么就会结束调用,如果没有则继续轮询。

    3. 多路复用IO

    多路复用IO模型是依赖内核具体实现的。如果系统没有select,poll,epoll等功能,那么设计层面是不能设计出来多路复用的。

    “select调用是内核级别的,可以等待多个socket,能实现同时对多个IO端口进行监听,当其中任何一个socket的数据准好了,就能返回进行可读然后进程再进行recvform系统调用,将数据由内核拷贝到用户进程,这个过程是阻塞的。”

    select有一些明显的不足:

    (1)调用select,需要把fd集合从用户态拷贝到内核态,开销在fd很多时,开销会很大;

    (2)调用select需要在内核遍历传递进来的所有fd,在fd很多时开销很大;

    (3)select支持的fd数量小,默认是1024;

    poll和select其实是差不多的,只是poll的fd表示方法不一样,这让poll支持的fd数量远远不止1024个

    epoll是为了改进上面的一些不足之处而升级的。从上面可以看出,fd集合需要在内核态和用户态之间不停的移动,每次主动轮询数据时候,要遍历内核态中所有的fd,这两个方面就会出现很多重复的事情要做,epoll对这两个方面进行了优化。

    epoll提供了三个函数,epoll_create,epoll_ctl和epoll_wait,epoll_create创建一个epoll句柄;epoll_ctl是注册要监听的事件类型;epoll_wait则是等待事件的产生。

    首先epoll会调用epoll_creaet创建一个epoll的句柄(fd1),之后通过调用epoll_ctl将新的句柄添加到fd1上,并且标记上EPOLL_CTL_ADD,这一步会把生成的新的句柄fd2拷贝到内核态中,每次只要有新的句柄产生,就会产生一次用户态到内核态的拷贝。这样就避免了每次都要把整个fd集合全部拷贝到内核中。epoll会在内核中额外开辟一块空间,如果某一个fd准备就绪,那么这个fd就会被复制到新的空间中,epoll_wait方法会专门去这块空间中去获取fd的状态,这种epoll_wait就不用轮询内核中整个fd集合,提高了效率。

  • 相关阅读:
    tensorflow在文本处理中的使用——Doc2Vec情感分析
    tf.squeeze()
    tf.concat()
    tf.slice()
    WebService到底是什么?
    Webservice工作原理及实例
    Iterator,foreach遍历小计
    谈谈今年很火的区块链 CDN
    Java 反射简介(转载)
    Ajax二级联动简单实例
  • 原文地址:https://www.cnblogs.com/markytsai/p/13382784.html
Copyright © 2011-2022 走看看