同步、异步与阻塞、非阻塞的理解

在学习到python网络编程,SocketServer.{ForkingMixIn|ThreadingMixIn}中,涉及到select的应用,由此了解到socket的setblocking模式,了解了socket有阻塞与非阻塞的区别,同时网上查询了一下,感觉对异步、同步的概念有些重叠,为此深入了解一下。

在知乎上查询上的部分解答:

在linux网络IO中涉及到如下模型:
(1)阻塞式IO
(2)非阻塞式IO
(3)IO多路复用
(4)信号驱动IO
(5)异步IO
**阻塞式I/O模型:**默认情况下,所有套接字都是阻塞的。怎么理解?先理解这么个流程,一个输入操作通常包括两个不同阶段:
(1)等待数据准备好;
(2)从内核向进程复制数据。
对于一个套接字上的输入操作,第一步通常涉及等待数据从网络中到达。当所有等待分组到达时,它被复制到内核中的某个缓冲区。第二步就是把数据从内核缓冲区复制到应用程序缓冲区。 好,下面我们以阻塞套接字的recvfrom的的调用图来说明阻塞

在这里插入图片描述
标红的这部分过程就是阻塞,直到阻塞结束recvfrom才能返回。
非阻塞式I/O: 以下这句话很重要:进程把一个套接字设置成非阻塞是在通知内核,当所请求的I/O操作非得把本进程投入睡眠才能完成时,不要把进程投入睡眠,而是返回一个错误。看看非阻塞的套接字的recvfrom操作如何进行
在这里插入图片描述
可以看出recvfrom总是立即返回。
**I/O多路复用:**虽然I/O多路复用的函数也是阻塞的,但是其与以上两种还是有不同的,I/O多路复用是阻塞在select,epoll这样的系统调用之上,而没有阻塞在真正的I/O系统调用如recvfrom之上。如图
在这里插入图片描述
**信号驱动式I/O:**用的很少,就不做讲解了。直接上图
在这里插入图片描述
**异步I/O:**这类函数的工作机制是告知内核启动某个操作,并让内核在整个操作(包括将数据从内核拷贝到用户空间)完成后通知我们。如图:
在这里插入图片描述
其实前四种I/O模型都是同步I/O操作,他们的区别在于第一阶段,而他们的第二阶段是一样的:在数据从内核复制到应用缓冲区期间(用户空间),进程阻塞于recvfrom调用。相反,异步I/O模型在这两个阶段都要处理。
再看POSIX对这两个术语的定义:
同步I/O操作:导致请求进程阻塞,直到I/O操作完成;
异步I/O操作:不导致请求进程阻塞。
好,下面我用我的语言来总结一下阻塞,非阻塞,同步,异步阻塞,
**非阻塞:**进程/线程要访问的数据是否就绪,进程/线程是否需要等待;
**同步,异步:**访问数据的方式,同步需要主动读写数据,在读写数据的过程中还是会阻塞;异步只需要I/O操作完成的通知,并不主动读写数据,由操作系统内核完成数据的读写。

https://www.zhihu.com/question/19732473/answer/26101328

在这里插入图片描述
在这里插入图片描述

总结

在这里插入图片描述
**同步:**执行一个操作之后,等待结果,然后才继续执行后续的操作。

异步:执行一个操作后,可以去执行其他的操作,然后等待通知再回来执行刚才没执行完的操作。

**阻塞:**进程给CPU传达一个任务之后,一直等待CPU处理完成,然后才执行后面的操作。

**非阻塞:**进程给CPU传达任我后,继续处理后续的操作,隔断时间再来询问之前的操作是否完成。这样的过程其实也叫轮询。

    阻塞、非阻塞、多路IO复用,都是同步IO,异步必定是非阻塞的,所以不存在异步阻塞和异步非阻塞的说法。真正的异步IO需要CPU的深度参与。换句话说,只有用户线程在操作IO的时候根本不去考虑IO的执行全部都交给CPU去完成,而自己只等待一个完成信号的时候,才是真正的异步IO。所以,拉一个子线程去轮询、去死循环,或者使用select、poll、epool,都不是异步。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值