阻塞非阻塞同步异步调用方式以及五种IO模型

一.阻塞与非阻塞

  • 阻塞
    在网络通信中,我们会调用read,recv等函数去读取网络中发来的数据,数据先会来到内核的TCP缓冲区中,然后再将数据从内核拷贝到用户的buff中,当缓冲区中没有数据时,read默认会阻塞,也就是将整个进程挂起,等到数据的到来,直到数据就绪,才会被唤醒继续执行;
    包括send,send做的工作是将数据从user拷贝到kernel,但是有时内核缓冲区没有足够的位置,也会发生阻塞;
    阻塞还是不阻塞的过程由read(),send()等函数内部的实现所决定.
  • 缺点:需要等待的时间不确定,不过可以设置超时时间,开启一个专门读取或者发送线程去干这些事等一些手段控制.

在这里插入图片描述

  • 非阻塞 NIO
    与阻塞不同,同样的当我们调用read等函数时,当内核缓冲区还没有数据到,read会立刻返回,不会等待,所以当前的进程不会被OS挂起;也就是说在一定程度上保证了当前进程不会被挂起.

  • 分析:没有数据也会返回,所以需要我们循环不断的去读取;或者可以用IO复用函数将我们想要监控的fd交给他们,有数据到了内核帮我们处理.

二.将fd修改为非阻塞:

#include<fcntl.h>
在这里插入图片描述
三.同步异步

  • 同步:可认为是一种顺序执行,是一种依赖的关系.在实际开发中,我们某些函数A的执行依赖其他函数B的返回,也就是A函数的执行要等到B函数执行完毕,A在那里死等B.
  • 异步:可以认为是一种并行处理方式,就比如说我们看视频需要加载,我们不是等待,而是可以给女朋友回个微信(也有可能是男朋友),当然你也可能是实力单身.
    来看一个比专业一点的回答:
所谓同步,就是在发出一个功能调用时,在没有得到结果之前,该调用就不返回

当一个异步过程调用发出后,调用者不能立刻得到结果。实际处理这个调用的部件在完成后,
通过状态,通知和回调来通知调用者. 如信号机制,回调函数等

(在描述阻塞和非阻塞的时候并没有感觉到那个效率高,这里明显感觉异步调用可以干很多事!)

四.五种IO模型: 网上大佬举了个很合适的例子

  1. 阻塞IO:
A拿着一支鱼竿在河边钓鱼,并且一直在鱼竿前等,在等的时候不做其他的事情,十分专心
只有鱼上钩的时,才结束掉等的动作,把鱼钓上来。

在这里插入图片描述

  1. 非阻塞IO:
B也在河边钓鱼,但是B不想将自己的所有时间都花费在钓鱼上,
在等鱼上钩这个时间段中,B也在做其他的事情(一会看看书,一会读读报纸,一会又去看其他人的钓鱼等)
但B在做这些事情的时候,每隔一个固定的时间检查鱼是否上钩。
一旦检查到有鱼上钩,就停下手中的事情,把鱼钓上来。


每次客户询问内核是否有数据准备好,即文件描述符缓冲区是否就绪。
当有数据报准备好时,就进行拷贝数据报的操作。
当没有数据报准备好时,也不阻塞程序,内核直接返回未准备就绪的信号,等待用户程序的下一个轮寻。

在这里插入图片描述

  1. 信号驱动IO:
C也在河边钓鱼,但与A、B不同的是,C比较聪明,他给鱼竿上挂一个铃铛,
当有鱼上钩的时候,这个铃铛就会被碰响,C就会将鱼钓上来。 

信号驱动IO模型,应用进程告诉内核:
当数据报准备好的时候,给我发送一个信号,对SIGIO信号进行捕捉,
并且调用我的信号处理函数来获取数据报。

在这里插入图片描述

  1. IO多路转接(IO复用):
D同样也在河边钓鱼,但是D生活水平比较好,D雇了个下人帮他看着所有的鱼竿,
一旦哪个鱼竿有动静,就将这个鱼竿交给老板D,老板去收鱼就好了.实际上这个下人是内核.emmmm

select  poll  epoll

在这里插入图片描述

  1. 异步IO:
E也想钓鱼,但E有事情,于是他雇来了F,让F帮他等待鱼上钩,E去把妹,一旦有鱼上钩,
F就打电话给E,E就会将鱼钓上去。 (打电话也就是 信号,回调等通知手段)

在这里插入图片描述

注意区分这里的同步异步和并发编程中的同步异步.

看了一些讲的比较好的博文,这篇还不错:
https://blog.csdn.net/ZYZMZM_/article/details/97814160

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值