zoukankan      html  css  js  c++  java
  • 关于:socket阻塞、非阻塞,同步、异步、I/O模型

    一般提起I/O模型的时候,这几个概念总是有点让人模糊,其实如果理解了,还是比较好区分的。

    Ps:参考《UNIX网络编程:卷一》

    1、“同步”和“异步”

    如果单单理解这两个概念还是很好区分的:

    同步:处理事情的的时候需要串行执行,也就是说做完一件再去做另一件,不管是否需要时间等待。也就是说,无条件等待这件事被完成。

    异步:处理事情的的时候可以并发,即可以同时做几件事,不需要一件事做完再做另一件事。也就是说,当一件事完成的时候,通知我完成了就OK了

    。(这里需要注意理解的是,用于真正处理事件的是其他的处理部件(函数))


    2、“阻塞”和“非阻塞”

    阻塞:简单理解就是说我想要做这件事,但是现在还不能去做,那么我必须挂起等待。举个不太恰当的例子:去饭店吃饭,   没有座位了,我就只能一

    直等着,等到有座位。

    非阻塞:简单理解就是说我想要做这件事,但是现在还不能去做,那么我立即返回。但是需要注意,非阻塞情况下需要不断的      去轮循查看是不是可

    以做这件事了。用上面的例子,去饭店吃饭,没有座位,那么我先到隔壁的休息室坐着等着,每5min去看一次,是不是有座位了。


    3、综合理解

    “同步”和“异步”指的是整体上我是不是需要去等待。“阻塞”和“非阻塞”指的是当一件事不能被立即处理的时候,是不是需要等待。也可以这么理解,

    “同步”和“异步”的在是不是需要等待方面的处理优先级比“阻塞”和“非阻塞”高。或许这句话说得不是很准确,

    但是确实可以这样理解:只有在同步的情况下才会有“阻塞”和“非阻塞”之说,异步情况,必须是不阻塞的!

    > 同步:阻塞 / 非阻塞

    > 异步:

    关于阻塞/非阻塞,在网络编程中大部分都是应用在是不是需要等待数据就绪,一般当我们需要读数据的时候,这个时候数据还没有准备好,那么如果

    是阻塞套接字,那么需要一直阻塞等到数据准备就绪;如果是非阻塞套接字,那么立刻返回,一定周期时间后再次轮询看看是不是准备好了!


    一般情况使用阻塞情况就OK,但是并发性就难以保证,不过我们还是可以使用多线程技术来处理,每一个套接字使用一个线程处理,那么谁睡阻塞和

    我没大关系,但是线程多了之后再性能上难以保证。


    关于“非阻塞”应用点:我们时刻需要知道的是非阻塞在数据还没有就绪的时候,就立即返回,那么在这一点上做一些文章就得到了select这样的I/O复用

    的套接字。经过改良之后,select本质还是轮询套接字,只不过,这一次轮询的不是一个套接字,如果只轮询一个套接字,那么着实有点浪费啊~select

    可以轮询多个套接字,看看那些套接字准备好了数据,然后处理就OK,这样的话,select将非阻塞IO的效率就提高很多了。

    4、常用5中I/O模型(UNIX网络编程)

    1) 阻塞I/O
    2) 非阻塞I/O
    3) I/O复用(select 、poll、epoll)
    4) 信号驱动I/O (signal driven I/O (SIGIO))

    5) 异步I/O (asynchronous I/O (the POSIX aio_functions))

    pre:在前面已经说过,只有在同步下,才有阻塞/非阻塞之说,异步就是异步,没有任何等待。。。

    那么上面的5中IO,只有最后一个才是真正的异步IO。

    1、阻塞I/O

    按照上面的说法我们可以说成是“同步阻塞IO”,那么也就是说这个会一直阻塞,阻塞到数据拷贝结束!

    看下图(下面所有图示来自:UNIX网络编程:卷一)

    最左边的那句话“进程阻塞于recvfrom的调用”说明在整个过程中进程都是阻塞的!右边的“等待数据”这句话说明,当数据没有准备好的时候,由于现在

    是“阻塞”模式,那么需要等待数据。同时注意,在copy数据的时候,必须等待。

    2、非阻塞I/O

    按照我们的说法其实是:“同步非阻塞IO”,当数据没有准备的好的时候,需要反复轮询看看是不是准备好,其实这个时候进程本质上也是在等待,只不

    过等待是无止境的等待轮询的结果。

     

    最左边的那句话“进程反复调用recvfrom等待返回成功指示”说明本质还是在等待,只不过换了个方式玩而已!即:不断轮询,不断等待。。。同时注意

    ,在copy数据的时候,必须等待。

    3、I/O复用

    I/O复用模型一般有select、poll、epoll函数,其实按照我们上面的说法,叫“同步I/O复用”。这个本质上是“非阻塞”模型,但是是演化之后的升级版模型

    。拿select来说,这个函数一次可以轮询很多个套接字,而不仅仅上面那样只轮询一个套接字,select轮询过程中只要有一个套接字上面数据准备好,

    那么就可以被处理了。这样的话比上面的优势就体现出来了,上面的非阻塞模式,如果在一个点上阻塞了,那么即使后面存在可以读写的套接字,那也得跟着等待,所有select提高很大效率。

    同时注意,在copy数据的时候,必须等待。

    4、信号驱动I/O

    这个也是“非阻塞IO”模型一种演化。在套接口进行信号驱动I/O,并安装一个信号处理函数,进程继续运行并不阻塞。当数据准备好时,进程会收到一个

    SIGIO信号,可以在信号处理函数中调用I/O操作函数处理数据。

    注意:当数据没有就绪的时候,进程不会阻塞,继续运行,当数据就绪的时候,通过信号通知进行处理数据!

    同时注意,在copy数据的时候,必须等待。

    5、 异步I/O

    没有阻塞,只需要发出一个处理命令,然后自己做自己的事,然后那件事被处理结束之后,通知说事件结束,处理一下收尾工作就OK。

     

    注意:在copy数据的时候,不需要等待!!

    总结:一个IO操作基本包括两个阶段:

    (1)等待数据准备就绪
    (2)从内核向进程复制数据


    如果是:

    同步阻塞:那么会一直阻塞下去。数据没有就绪,那么需要等待,拷贝数据也需要等待。

    同步非阻塞:其实也需要一直等待,只不过方式不同。数据没有准备好,那么需要轮询,这里衍生了像I/O复用这样更高效率的IO手段。拷贝数据需要

    等待。

    异步:只需要处理头尾,中间无需等待。

    OK,总结完毕..

  • 相关阅读:
    iOS 阶段学习第23天笔记(XML数据格式介绍)
    iOS 阶段学习第22天笔记(JSON数据格式介绍)
    iOS阶段学习第21天笔记(ARC内存管理-Copy-代理)
    iOS阶段学习第20天笔记(MRC内存管理)
    iOS阶段学习第19天笔记(协议-Protocol)
    iOS阶段学习第18天笔记(Plist-Archiver-归档与解归档操作)
    iOS阶段学习第17天笔记(NSFileManager-NSFileHandle-文件操作)
    Mac系统与Xcode的一些常用操作介绍
    iOS阶段学习第16天笔记(Category-NSSet-SEL-NSIndexSet 操作)
    iOS UIButton添加圆角,添加边框
  • 原文地址:https://www.cnblogs.com/linux-bfbdxj520/p/11360482.html
Copyright © 2011-2022 走看看