美文网首页
JavaNIO-通道06 Linux 网络IO模型

JavaNIO-通道06 Linux 网络IO模型

作者: 贪睡的企鹅 | 来源:发表于2019-07-25 16:22 被阅读0次

    1 Linux 网络IO模型

    读取网络数据过程

    /** 获取SocketChannel**/
    SocketChannel socketChannel = serverSocketChannel.accept();
    /** 读取客户端发送数据 **/
    ByteBuffer byteBuffer = ByteBuffer.allocate(100);
    socketChannel.read(byteBuffer);
    System.out.println(new String(byteBuffer.array()));
    
    image
    • 1、应用程序发起读数据操作,JVM会发起read()系统调用。

    • 2、这时操作系统OS会进行一次上下文切换(把用户空间切换到内核空间)

    • 3、通过磁盘控制器把数据copy到内核缓冲区中,这里的就发生了一次DMA Copy

    • 4、然后内核将数据copy到用户空间的应用缓冲区中,发生了一次CPU Copy

    • 5、read调用返回后,会再进行一次上下文切换(把内核空间切换到用户空间)

    对于一次IO访问,数据会先被拷贝到操作系统内核的缓冲区中,然后才会从操作系统内核的缓冲区拷贝到应用程序的缓冲区,最后交给进程。所以说,当一个read操作发生时,它会经历两个阶段:

    • 1. 等待数据准备(从网络设备拷贝到操作系统缓冲区)
    • 2. 将数据从内核拷贝到进程中(从操作系统缓冲区拷贝到用户进程缓冲区)

    正式因为这两个阶段,linux系统产生了下面五种网络模式的方案: 阻塞 I/O(blocking IO),非阻塞 I/O(nonblocking IO), I/O 多路复用( IO multiplexing), 信号驱动 I/O( signal driven IO),异步 I/O(asynchronous IO)

    阻塞IO

    同步阻塞IO通常表示当用户进程(java进程)底层调用操作系统recv()/recvfrom()函数接收数据。用户进程会在内核空间准备数据,内核空间拷贝到用户空间这两个过程都是阻塞的。

    image
    流程
    • 用户进程调用read,发起system call,用户进程阻塞。

    • 开始第一阶段,系统kernel准备数据(从网络设备拷贝到内核缓冲区)。

    • 开始第二阶段,将数据从内核拷贝到了用户空间。

    • 进程解除阻塞。

    非阻塞I/O模型

    非阻塞I/O模型通常表示当用户进程(java进程)底层调用操作系统recv()/recvfrom()函数接收数据。内核空间数据没有准备好时会返回一个错误表示不接收处理,应用进程需要不断的询问直到内核空间数据准备好后接收处理,将内核空间数据拷贝到用户空间中返回成功

    image
    流程
    • 用户进程调用read,发起system call,如果操作系统kernel数据准备还没有准备好,操作系统kernel并不会block用户进程,而是立刻返回一个error。

    • 用户进程获取read操作结果进行判断,如果结果是一个error时,它就知道内核空间数据还没有准备好,可以等待一段时间后继续发出read操作

    • 当操作系统kernel数据准备,并且又再次收到了用户进程的system call;。

    • 将内核空间数据拷贝到了用户空间内存,然后返回。

    I/O多路复模型

    I/O多路复用实际上就是用select, poll, epoll监听多个io对象在内核缓存数据的准备过程,当io对象有变化(有数据)的时候就通知对应IO的用户进程。

    image
    流程
    • 用户进程调用select,发起system call,同时整个进程会被block,而同时,操作系统kernel上注册了一个监听事件.监听系统kernel数据是否准备好。

    • 当系统kernel准备数据,select就会返回;

    • 这个时候用户进程再调用read操作,将数据从内核空间数据中拷贝到用户空间并返回

    信号驱动IO

    image
    • 用户进程调用read,发起system call,系统kernel准备数据,操作系统kernel并不会block用户进程。

    • 系统kernel准备数据,就会产生一个信号通道用户进程

    • 用户进程接收信号,将数据从内核空间数据中拷贝到用户空间。

    异步 I/O

    image

    (1)用户进程发起read操作之后,立刻就可以开始去做其它的事。

    (2)而另一方面,从kernel的角度,当它受到一个asynchronous read之后,首先它会立刻返回,所以不会对用户进程产生任何block。

    (3)然后,kernel会等待数据准备完成,然后将数据拷贝到用户内存,当这一切都完成之后,kernel会给用户进程发送一个signal,告诉它read操作完成了。

    2 同步、异步、阻塞、非阻塞

    同步与异步:描述的是用户线程与内核的交互方式,同步指用户线程发起IO请求后需要等待或者轮询内核IO操作完成后才能继续执行;而异步是指用户线程发起IO请求后仍然继续执行,当内核IO操作完成后会通知用户线程,或者调用用户线程注册的回调函数。

    阻塞与非阻塞:描述是用户线程调用内核IO操作的方式,阻塞是指IO操作需要彻底完成后才返回到用户空间;而非阻塞是指IO操作被调用后立即返回给用户一个状态值,无需等到IO操作彻底完成。

    相关文章

      网友评论

          本文标题:JavaNIO-通道06 Linux 网络IO模型

          本文链接:https://www.haomeiwen.com/subject/kpghrctx.html