11.协程与异步IO

1. 并发、并行、同步、异步、阻塞、非阻塞

  • 并发和并行:

    并发: 一个时间段内,有几个程序在同一个cpu上运行,但是任意时刻只有一个程序在cpu上运行

    并行: 任意时刻点上, 有多个程序同时运行在多个cpu上

实际举例说明:

问题 - 喝茶
    情况: 开水没有,水壶要洗,茶壶茶杯要洗;火生类, 茶叶也有了。怎么办?
所需时间:
    洗水壶: 3
    灌凉水: 1
    洗茶壶: 3
    洗茶杯: 3
    拿茶叶: 1
    泡茶: 1
    烧开水: 30

并发版本:
老赵(cpu1):
办法1 洗水壶,灌凉水, 放在火上;等待水烧开的时间里, 洗水壶,洗茶杯,拿茶叶;等水开了,泡茶喝。
        总用时: 3+1+30+1 = 35
办法2:  先做好一些准备工作, 洗水壶,洗茶壶茶杯,拿茶叶;也切就绪,灌水烧水;坐等水开了泡茶喝。
        总用时: 3+3+3+1+30+1 = 41
办法3: 洗净水壶,灌上凉水,放在火上,坐等水开;水开之后, 急急忙忙找茶叶,洗茶壶茶杯,泡茶喝。
        总用时: 3+1+30+3+3+1 = 41


并行版本:
老赵(cpu1):洗好水壶,灌上凉水,放在火上
老李(cpu2):洗茶壶
老李(cpu2):洗茶壶
老谢(cpu3):洗茶杯
        总用时: 31
  • 同步和异步:

    同步: 代码调用IO操作时,必须等待IO操作完成才返回的调用方式

    异步: 代码调用IO操作时,不必等IO操作完成就返回的调用方式

  • 阻塞和非阻塞:

    阻塞: 调用函数时,当前线程被挂起 (比如前面socket编程中socket.connect就是阻塞的)

    非阻塞: 调用函数时,当前线程不会被挂起,而是立即返回

例子:

小乐爱喝茶,废话不说,煮开水。
出场人物:小乐,水壶两把(普通水壶,简称水壶;会响的水壶,简称响水壶)。
   1 小乐把水壶放到火上,立等水开。(同步阻塞)
     ——   小乐觉得自己有点傻
   2 小乐把水壶放到火上,去客厅看电视,时不时去厨房看看水开没有。(同步非阻塞)
     ——  小乐还是觉得自己有点傻,于是变高端了,买了把会响笛的那种水壶。水开之后,能大声发出呜呜~~~~的噪音。
   3 小乐把响水壶放到火上,立等水开。(异步阻塞)
     ——  小乐觉得这样傻等意义不大
   4 小乐把响水壶放到火上,去客厅看电视,水壶响之前不再去看它了,响了再去拿壶。(异步非阻塞)
     ——  小乐觉得自己聪明了。


所谓同步异步,只是对于水壶而言。
 普通水壶,同步;响水壶,异步。
 虽然都能干活,但响水壶可以在自己完工之后,提示小乐水开了。这是普通水壶所不能及的。
 同步只能让调用者去轮询自己(情况2中),造成小乐效率的低下。

所谓阻塞非阻塞,仅仅对于小乐而言。
—— 立等的小乐,阻塞;看电视的小乐,非阻塞。

情况1和情况3中小乐就是阻塞的,媳妇喊他都不知道。

虽然3中响水壶是异步的,可对于立等的小乐没有太大的意义。

所以一般异步是配合非阻塞使用的,这样才能发挥异步的效用。

2. I/O多路复用介绍(select, poll, epoll)

  • Unix下五种I/O模型:

1)阻塞I/O(blocking I/O2)非阻塞I/O (nonblocking I/O3)I/O复用(select 和poll) (I/O multiplexing)
4)信号驱动I/O (signal driven I/O (SIGIO))
5)异步I/O (asynchronous I/O (the POSIX aio_functions))

前四种都是同步,只有最后一种才是真正的异步IO。

阻塞I/O:

简介:进程会一直阻塞,直到数据拷贝完成

描述:应用程序调用一个IO函数,导致应用程序阻塞,等待数据准备好。
如果数据没有准备好,一直等待….数据准备好了,从内核拷贝到用户空间,IO函数返回成功指示。

非阻塞IO:

简介:非阻塞IO通过进程反复调用IO函数(多次系统调用,并马上返回);在数据拷贝的过程中,进程是阻塞的;

描述:我们把一个SOCKET接口设置为非阻塞就是告诉内核,当所请求的I/O操作无法完成时,
不要将进程睡眠,而是返回一个错误。这样我们的I/O操作函数将不断的测试数据是否已经准备好,
如果没有准备好,继续测试,直到数据准备好为止。在这个不断测试的过程中,会大量的占用CPU的时间。


IO复用:

简介:主要是select和epoll;对一个IO端口,两次调用,两次返回,
比阻塞IO并没有什么优越性;关键是能实现同时对多个IO端口进行监听;

描述:I/O复用模型会用到select、poll、epoll函数,这几个函数也会使进程阻塞,
但是和阻塞I/O所不同的的,这两个函数可以同时阻塞多个I/O操作。而且可以同时对多个读操作,
多个写操作的I/O函数进行检测,直到有数据可读或可写时,才真正调用I/O操作函数。


信号驱动IO:

简介:两次调用,两次返回;

描述:首先我们允许套接口进行信号驱动I/O,并安装一个信号处理函数,进程继续运行并不阻塞。
当数据准备好时,进程会收到一个SIGIO信号,可以在信号处理函数中调用I/O操作函数处理数据。


  • 5
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值