zoukankan      html  css  js  c++  java
  • Linux网络IO模型

    同步阻塞IO

     

    • 当应用程序想要从socket流获取数据时,进程调用recvfrom I/O API:
      • 当socket有数据进来,recvfrom调用内核,内核将数据从网卡拷贝到内核空间,再从内核空间拷贝到应用程序空间,recvfrom才返回给应用程序进行处理,它是一个同步操作,进程会一直阻塞直到数据拷贝完。
      • 当没有数据进来时,进程会一直等待(休眠状态)直到有数据进来,再执行上述动作,在这个等待和执行的期间,当前应用程序一直阻塞。

    同步非阻塞IO

    • 当应用程序想要从socket流获取数据时,进程调用recvfrom I/O API:
      • 当没有数据时,recvfrom会直接返回错误告知进程,进程开始一直重试调用(轮询,非休眠,当然在重试期间,进程也可以去做其他事情了)recvfrom,直到有数据,再进行处理,这个重试的过程非常消耗cpu(所以用的也比较少)。

    IO复用模型(JAVA中称为NIO)

    • 应用进程不再直接请求recvfrom I/O API,而是请求select/poll API,阻塞点在select/poll方法上
      • 进程都要进行IO请求时,都请求的是select/poll API,此时在select/poll API中维护了一个容器来记录这些socket,select/poll会去轮询这个容器,类似于非阻塞式IO模型,当发现有socket变为可读时,调用recvFrom从指定socket流中读取数据返回给应用程序。 
      • 当应用程序只从单个socket中读取数据,它跟BIO区别不大,当应用程序要从多个socket中读取数据(即多个请求时),它可以将这些socket都交给select监控,一旦有socket描述符符合条件,调用IO读取数据。
      • 当连接数很多时,每次遍历socket非常影响性能。
      • 用epoll方法可以优化,与select/poll不同,它不需要一直轮询得到哪个socket有数据,而是监控的sockets中谁有数据,谁就主动通知它,它再去调用IO返回数据给应用程序。java NIO selector则是使用这种方式。

    信号驱动式IO模型   

    • 应用程序建立信号处理程序,当需要调用IO API时,给内核发送信号,内核确认信号返回。
      • 当内核监测到有数据,可以进行IO调用的时候,就发送信号给应用程序,此时应用程序再去调用recFrom,处理数据。
      • 等待信号的过程中应用程序没有被阻塞。
      • 可以通知应用程序处理数据,也可以通知应用程序可以开始读取数据。

    异步IO模型

    •  应用进程告知内核启动某个动作,内核在整个过程全部处理完成后(数据已经被拷贝到应用程序的缓冲中)再通知进程,直接处理数据。
      • 它与上面提到的信号驱动的IO模型区别在于,信号驱动的IO模型是通知应用进程去调用recFrom执行IO操作,而异步IO是在内核将IO操作全部执行完成后去通知应用程序直接处理。

    各种IO模型的比较:直接贴上原文(来源:UNIX网络编程卷I 159)

     根据之前的描述,这段应该很容易理解,不多解释了。

    同步IO和异步IO的的对比:

     可以看出同步跟异步的区别在于,同步IO一定会阻塞应用进程直到IO处理完成,而异步IO操作都是由内核操作完成后直接通知应用程序处理,不会阻塞应用进程。

     

  • 相关阅读:
    [BJOI2006]狼抓兔子
    [HNOI2016]最小公倍数
    hihocoder 1419 重复旋律4
    [NOI2015]品酒大会
    [SDOI2016]生成魔咒
    [ZJOI2009]狼和羊的故事
    BZOJ4361 isn
    [SDOI2009]虔诚的墓主人
    BZOJ 3329 Xorequ
    [ZJOI2013]丽洁体
  • 原文地址:https://www.cnblogs.com/indecy/p/11612727.html
Copyright © 2011-2022 走看看