• 忘掉天地
  • 仿佛也想不起自己
bingliaolongBingliaolong  2020-04-28 03:20 Aet 隐藏边栏 |   抢沙发  4 
文章评分 2 次,平均分 5.0

介绍

网络应用需要处理解决的主要可以归为两大类问题:

  1. 网络I/O
  2. 数据计算

网络I/O的本质是socket的读取,socket在linux系统被抽象为流,I/O可以理解为对流的操作。这个操作又分为两个阶段:

  1. 等待流数据准备(wating for the data to be ready)
  2. 从内核向进程复制数据(copying the data from the kernel to the process)

对于流而言:

  • 第一步通常涉及等待网络上的数据分组到达,然后被复制到内核的某个缓冲区
  • 第二步把数据从内核缓冲区复制到应用进程缓冲区

概念

同步&&异步

可根据一个函数调用之后,是否直接返回结果来判断:

  • 如果函数调用之后挂起了,直到获得了结果它才返回,这是同步的方式
  • 如果函数调用之后马上返回,等数据到达再通知函数,这是异步的方式
    • 状态
    • 通知
    • 回调函数

阻塞&&非阻塞

  • 函数如果让线程挂起不再往下执行,该函数是阻塞的

组合分析

举例:

去银行办理业务(存钱、取钱以及其他),假如我们有两种方式可以选择到达柜台办理业务

  • 大家排成一条长队,银行依此按顺序给我们办理业务(同步)
  • 我们打印一个单号,等银行通知改到我这个号码办理业务的时候,我们再去柜台(异步)

同步阻塞

  • 效率最低
  • 专心排队,排队期间不干其他任何事

异步阻塞

  • 不用排队,等待通知号码(要自己去等),但是不能离开银行这个地方,要等待被通知。阻塞就阻塞在需要等待被通知,被通知之前不能离开

同步非阻塞

  • 效率比较低
  • 排队期间,还处理着别的事情,一边要看排没排到自己,一边还要忙别的

异步非阻塞

  • 效率更高
  • 不用排队,等待通知号码(不用自己等,到自己的号码了会有人来通知我们),期间可以做别的事情

解析

通常而言,同步阻塞,异步非阻塞。

什么情况是异步阻塞呢?

即函数调用之后并没有返回结果而注册了回调函数,非阻塞的情况下,函数也马上返回,可是如果此时函数不返回,那么此时就是阻塞的状态,等数据到达通知函数,依然是异步的过程。

模型分类

  • 同步模型(synchronous I/O)
    • 阻塞I/O(bloking I/O)
    • 非阻塞I/O(non-blocking I/O)
    • 多路复用I/O(multiplexing I/O)
    • 信号驱动式I/O(signal-driven I/O)
  • 异步I/O(asynchronous I/O)

阻塞I/O(bloking I/O)

在网络I/O的时候,进程发起recvform系统调用,然后进程就被阻塞了,什么也不干,直到数据准备好,并且将数据从内核复制到用户进程,最后进程再处理数据,在等待数据到处理数据的两个阶段,整个进程都被阻塞。不能处理别的网络I/O。

非阻塞I/O(non-bloking I/O)

在网络I/O时候,非阻塞I/O也会进行recvform系统调用,检查数据是否准备好,与阻塞I/O不一样,"非阻塞将大的整片时间的阻塞分成N多的小的阻塞, 所以进程不断地有机会 '被' CPU光顾"。

也就是说非阻塞的recvform系统调用调用之后,进程并没有被阻塞,内核马上返回给进程,如果数据还没准备好,此时会返回一个error。进程在返回之后,可以干点别的事情,然后再发起recvform系统调用。重复上面的过程,循环往复的进行recvform系统调用。

这个过程通常被称之为轮询

轮询检查内核数据,直到数据准备好,再拷贝数据到进程,进行数据处理。需要注意,拷贝数据整个过程,进程仍然是属于阻塞的状态。

多路复用I/O(multiplexing I/O)

可以看出,由于非阻塞的调用,轮询占据了很大一部分过程,轮询会消耗大量的CPU时间。

多路复用有两个特别的系统调用selectpoll。select调用是内核级别的。

select轮询相对非阻塞的轮询的区别

select可以等待多个socket,当其中任何一个socket的数据准好了,就能返回进行可读,然后进程再进行recvform系统调用,将数据由内核拷贝到用户进程,当然这个过程是阻塞的。

多路复用有两种阻塞,select或poll调用之后,会阻塞进程,与第一种阻塞不同在于,此时的select不是等到socket数据全部到达再处理, 而是有了一部分数据就会调用用户进程来处理。如何知道有一部分数据到达了呢?监视的事情交给了内核,内核负责数据到达的处理。

多路复用的特点是通过一种机制一个进程能同时等待IO文件描述符,内核监视这些文件描述符(套接字描述符),其中的任意一个进入读就绪状态,select, poll,epoll函数就可以返回。

对于监视的方式,又可以分为 selectpollepoll三种方式。

异步I/O(asynchronous I/O)

相对于同步I/O,异步I/O不是顺序执行。用户进程进行aio_read系统调用之后,无论内核数据是否准备好,都会直接返回给用户进程,然后用户态进程可以去做别的事情。等到socket数据准备好了,内核直接复制数据给进程,然后从内核向进程发送通知。

I/O两个阶段,进程都是非阻塞的。

本文为原创文章,版权归所有,欢迎分享本文,转载请保留出处!

bingliaolong
Bingliaolong 关注:0    粉丝:0 最后编辑于:2021-11-20
Everything will be better.

发表评论

表情 格式 链接 私密 签到
扫一扫二维码分享