zoukankan      html  css  js  c++  java
  • socket_IO模型

    1 背景知识

    1.1 用户空间和内核空间

    比如32位系统,寻址空间是4G。内存分为用户空间和内核空间,内核空间仅供内核使用,用户空间给各个进程使用。os的核心是内核,只有内核可以访问被保护的内存空间。为了保证进程无法直接操作内核 ,在用户空间的进程无法访问内核空间。

    系统调用函数运行于内核态,但是向用户态开放接口。

    对于磁盘,网卡等设备,进程都无法直接访问,所以相关数据都用经过系统调用。

    1.2 进程阻塞

    正在执行的进程,由于期待的事件未发生,比如io操作未完成,新数据未到达,就由系统自动执行阻塞,由运行状态变为阻塞状态。所以,进程的阻塞是自身的自动行为,只有处于运行状态(获取cpu时间片)的进程才能转为阻塞状态。并且处于阻塞状态的进程不占用cpu。

    1.3 文件描述符(句柄)

    fd是指向具体文件的一个引用。

    fd是一个非负整数。当进程打开一个新文件或者socket,系统就为该文件分配一个fd,用来标识这个文件,这个分配的数字从0开始。系统默认情况下,限制每个进程能打来的文件为1024。

    1.4 标准io

    在标准io机制中,在内核中有页缓冲(内核高速缓冲),在用户空间有流缓冲。

    对于读操作,数据首先被读到页缓冲(当页缓冲中没有该数据),然后再拷贝到进程的内存地址。

    对于写操作,数据先被写到流缓冲,然后将多次写操作一次性写到页缓冲(减少系统调用),页缓冲再将多次写操作一次性写到磁盘(提高磁盘io效率)

    2  linux中的几种IO模型

    网络io的本质是socket的读取。对于一次网络io请求,有两个阶段:

      a 等待对端传递的数据就绪,就绪就拷贝到系统内核缓冲区,如果没有就绪就一直等待就绪。

      b 将内核缓冲区中的数据拷贝到进程的地址空间中。

    2.1 bio

    阻塞io是最常用的socket模型,并且默认情况下,所有socket都是阻塞的。

    首先,进程要请求网络数据时,使用recvfrom系统调用函数,然后系统调用从用户空间转移到内核空间运行。在内核空间等待对端数据报的到达,到达后内核空间的缓冲区后,把数据报拷贝到用户空间应用的缓冲地址。这个过程完成后,就返回获取成功给进程,进程没有延迟,开始处理数据报。

    整个过程中,进程都是自我阻塞的,在等待数据就绪的过程中,进程只能等待,无法作其他事情。好处是数据一就绪,进程就马上可以进行下一步的处理。

    2.2 nio

    在非阻塞模型中,当系统调用发现内核空间中未准备好数据,则直接返回一个error。进程会周期性轮训,询问内核空间是否准备好好数据。在此期间,进程不会等待(就是非阻塞)。

    相对于阻塞模型,非阻塞模型释放了进程,可以同时处理其他信息。但由于是周期性轮训,进程就不会在第一时间知道网路数据已准备好,所以增加了延迟。

    但如果进程要处理多个socket,非阻塞模型总是比阻塞模型效率更高。

    2.3 mio

    就是用select、epoll、poll,将多个socket的文件描述符传给内核,让内核去监听它们是否就绪。

    当用户进程调用 select,整个进程就被阻塞,当任何一个socket的数据在内核中 准备好了,select就会将可读条件返回。然后进程使用系统调用,将数据拷贝到用户空间(这一步就相当于bio)。

    nio是进程主动去询问多个socket的数据在内核中是否准备好,而mio是采用select去实时监听多个socket在内核中的数据是否准备好。

     2.4 aio

    进程使用aio_read函数将socket文件描述符,缓冲区指针、缓冲区大小和文件偏移传递给内核,并且告诉内核等数据准备好后直接传给aio_read中。

    进程不阻塞,数据准备好后,不需要进程再通过系统调用去读。

    2.5 比较

    bio,nio,mio,在数据拷贝到用户空间这个阶段进程会被阻塞,属于同步模型。

    aio在这个阶段进程不被阻塞

  • 相关阅读:
    poj 3280 Cheapest Palindrome(区间DP)
    POJ 2392 Space Elevator(多重背包)
    HDU 1285 定比赛名次(拓扑排序)
    HDU 2680 Choose the best route(最短路)
    hdu 2899 Strange fuction (三分)
    HDU 4540 威威猫系列故事――打地鼠(DP)
    HDU 3485 Count 101(递推)
    POJ 1315 Don't Get Rooked(dfs)
    脱离eclipse,手动写一个servlet
    解析xml,几种方式
  • 原文地址:https://www.cnblogs.com/jabbok/p/9292631.html
Copyright © 2011-2022 走看看