协程技术研究

先记住一句话,子程序是协程的一种特例。

Python yield

Python 中的 yield 保存一个 generator 函数的状态,generator 是一个特殊类型的迭代器(iterator)

import time

def consumer():
    r = ''
    while True:
        n = yield r
        print('[CONSUMER] Consuming %s...' % n)
        time.sleep(1)
        r = '200 OK'

def produce(c):
    c.next()
    n = 0
    while n < 5:
        n = n + 1
        print('[PRODUCER] Producing %s...' % n)
        r = c.send(n)
        print('[PRODUCER] Consumer return: %s' % r)
    c.close()

if __name__=='__main__':
    c = consumer()
    produce(c)

运行结果

[PRODUCER] Producing 1...
[CONSUMER] Consuming 1...
[PRODUCER] Consumer return: 200 OK
[PRODUCER] Producing 2...
[CONSUMER] Consuming 2...
[PRODUCER] Consumer return: 200 OK
[PRODUCER] Producing 3...
[CONSUMER] Consuming 3...
[PRODUCER] Consumer return: 200 OK
[PRODUCER] Producing 4...
[CONSUMER] Consuming 4...
[PRODUCER] Consumer return: 200 OK
[PRODUCER] Producing 5...
[CONSUMER] Consuming 5...
[PRODUCER] Consumer return: 200 OK

yield 相当于 return,主动交出程序的控制权,只不过它的状态保存到了内存中,还会再把控制权要回来的。第一次调用 consumer().next() 时会运行到 consumer 的 yield 这一行,然后权限又跑到了 producer 中。运行到 producer send 这一行,把权限给 consumer。consumer 和 producer 之间通过 yield 和 send 轮换掌握控制权。这样就实现了非线程方式的抢占式多任务。

next() 和 send() 调用是一样的,next() 不能传参数。

微信协程库 libco

libco 代码见 github,支持的功能

1.协程的创建与调度,使用 co_create,co_resume,co_yield 来搭建协程服务。和 Python 的 yield 方式很类似

2.基于网络的协程调度框架,可以通过网络事件来进行协程调度

libco 可以将系统的同步操作异步化,如标准 read 函数读取文件,系统打开文件描述符,阻塞在这里,一旦读取完毕返回。异步化就是调用 read 后直接返回,设置一个函数来处理读取完毕后返回的数据。把事件(读取完数据)注入到 epoll 中,同时 yield 交出线程控制权,一旦事件到来,切换到这个协程进行处理。

通过 hack 的方式替换掉了 read 函数,同理也可以替换掉和网络读写有关的接口,这样可以适用于 RPC 框架,这就是 libco 的主要思想。

参考

Linux Select 使用

select、poll、epoll之间的区别总结

谈谈对协程的理解

ucontext-人人都可以实现的简单协程库

转载于:https://my.oschina.net/lvyi/blog/793868

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值