linux网络模型

首先需要明确几个概念,什么是阻塞,非阻塞。什么是同步,异步。阻塞非阻塞是针对于cpu来说的。同步异步是针对于程序调用来说的。

概念

  • 阻塞
    阻塞从cpu的角度来看是该线程一直处于某一任务中,当该任务一直处于执行或者等待中,该线程也不能去做别的事情,只能一直等待。

  • 非阻塞
    非阻塞就是当线程执行某一个任务的时候,如果该任务处于执行或者等待中,那么cpu就可以调度该线程去做其他的事情,不会一直处于阻塞状态,避免造成资源浪费,提高系统性能,以及系统资源利用率。

  • 同步
    同步指的是程序执行层面,当程序执行一个任务的时候,如果不另启动线程去执行任务,则主线程一直同步等待任务执行完成,才会执行下面的代码。

  • 异步
    另起线程去执行任务,主线程继续执行任务一下的代码,当任务完成时,调用回调函数,返回结果。

Linux的网络模型

  1. 阻塞io
    当服务器监听tcp的数据接收缓冲区的时候,阻塞io模型是将监听线程阻塞,直到数据接收缓冲区有数据时将缓冲区数据从内核复制到用户空间中,然后对数据进行处理。

image

  1. 非阻塞io
    监听tcp的线程不在阻塞监听任务,一直等待接收数据,而是过段时间就去查看下接收数据缓冲区是否有数据。在其他的时间线程就去处理其他的事情。

image

  1. io复用模型
    非阻塞io的定时轮询来查看数据是否准备就绪仍然会消耗大量cpu的调度。io复用模型将线程阻塞在select操作上,select线程循环调用连接进来的socket,判断数据是否准备就绪,如果数据准备就绪,执行数据的空间复制和数据处理。io复用模型大致分两种。

    • select 一种是select。select/poll是顺序扫描fd(文件描述符,Linux中所有的资源描述都是文件)的,select的缺点就是扫描fd的个数是有限制的。
    • epoll 而epoll采用异步处理的机制,当某一个fd数据准备好时进行回调。

image

  1. 信号驱动io
    相比于io复用模型的select线程的轮询和阻塞,信号驱动模型使用异步调用的方式来通知线程进行数据处理,首先要开启信号处理功能,当连接进来的socket数据接收缓冲区有数据是通过信号通知线程去执行数据的空间复制和数据处理。这样减少了线程阻塞以及线程的轮询操作。

image

  1. 异步io
    异步io相比于信号驱动io不同之处在于监听进程何时接受信号,信号驱动io的信号接受是在数据到达内核缓冲区时,监听线程将数据从内核空间copy到用户空间的过程是阻塞的。而异步io的信号接收是在数据从内核空间copy到用户空间之后获得的,监听线程不会阻塞在内核数据copy的过程。

image