协程 I/O多路复用

对于操作系统来说协程是不可见的,不需要操作系统调度

协程(greenlet  注:小写g):如果检测到线程进入到IO阻塞,就去执行这个线程中的其他任务,即在线程中的任务中来回切换。

协程对操作系统有负担吗?

答:操作系统负责创建线程,但线程中的任务执行由程序决定,所以协程对操作系统没有负担。(协程是程序级别的操作单位)

1.协程就像是状态之间的来回切换和保存,所以是不是跟以前学的yield很像呢?

import time
def consumer():
    while True:
        res = yield                  
def producer():
    g = consumer()                    #切换到consumer
    next(g)
    for i in range(1000000):
        g.send(i)         #发送到yield,yield拿到后再返回到send,这样producrh和consumer之间来回                                                                
                          切换,像协程一样工作
start =time.time()
producer()
print(time.time() - start)

引子:协程任务之间切换(g.switch)

import time
from greenlet import greenlet
def play():
    print("start paly")
    g2.switch()
    print("end play")
    g2.switch()
def sleep():
    print("start sleep")
    g1.switch()
    print("end sleep")
g1 = greenlet(play)
g2= greenlet(sleep)
g1.switch()


start paly
start sleep
end play
end sleep

Process finished with exit code 0

gevent 基于greenlet实现的,多个任务交给gevent管理,遇到IO就使用greenlet进行切换 (不识别除自身外的阻塞,如time.sleep())

from gevent import monkey;monkey.patch_all()
 把下面所有的模块中的阻塞都打成一个包,然后gevent就可以识别这些阻塞事件了

from gevent import monkey;monkey.patch_all()
   # 把下面所有的模块中的阻塞都打成一个包,然后gevent就可以识别这些阻塞事件了
import time
import gevent
def play():   # 协程1
    print(time.time())
    print('start play')
    time.sleep(1)
    print('end play')
def sleep():  # 协程2
    print('start sleep')
    print('end sleep')
    print(time.time())

g1 = gevent.spawn(play)
g2 = gevent.spawn(sleep)
gevent.joinall([g1,g2]) #控制协程任务,执行完毕之后join立即结束阻塞

I/O多路复用

elect/epoll这个function会不断的轮询所负责的所有socket,当某个socket有数据到达了,就通知用户进程。它的流程如图:

异步I/O

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值