异步函数python 异步函数有哪些( 三 )


然后通过 args=coro.send(None) 与该函数碰撞 , 得到含有 delay 参数的字典作为 send 的返回值 。便可以判断出是否调用调度器的睡眠机制 。
最后在调度器中实现每一次协程列表循环结束后判断在睡眠列表中的协程是否有到时间的,到时间或时间超出则添加到运行协程列表中进入循环执行 。如果运行列表中的协程都执行完了 , 则查看睡眠列表中的协程中还需睡眠的最少时间,线程睡眠,睡眠完成再将其添加到运行队列 。
该装饰器能将一个比较耗时的计算函数封装为一个协程,使其可以被其他协程 await。在调度器中利用 send 函数的返回值可以获取它的类型为 background 、函数入口地址以及函数的传参,然后在调度器中按相应机制执行 。
第二部分 是在调度器中的修改:我们让调度器类拥有了一个私有的 concurrent.futures.ThreadPoolExecutor() 对象 。并在运行协程队列的循环判断中将 background 类型的操作提交给线程池对象,并将当前的协程移出运行队列,添加到 futures 队列中 。然后在每次运行队列循环后判断 futures 中的任务是否有完成的(使用的参数为一旦有任一任务完成或被取消都返回),如果主线程此时处于将要睡眠的状态,就等待相应的时间,没有的话则立刻返回,下次再查询,完成的任务将其所在协程带入运行队列,任务结果通过调度器 send 传回该协程 。
python异步有哪些方式yield相当于return,他将相应的值返回给调用next()或者send()的调用者 , 从而交出了CPU使用权,而当调用者再次调用next()或者send()的时候,又会返回到yield中断的地方,如果send有参数,还会将参数返回给yield赋值的变量,如果没有就和next()一样赋值为None 。但是这里会遇到一个问题,就是嵌套使用generator时外层的generator需要写大量代码,看如下示例:
注意以下代码均在Python3.6上运行调试
#!/usr/bin/env python# encoding:utf-8def inner_generator():
i = 0
while True:
i = yield iif i10:raise StopIterationdef outer_generator():
print("do something before yield")
from_inner = 0
from_outer = 1
g = inner_generator()
g.send(None)while 1:try:
from_inner = g.send(from_outer)
from_outer = yield from_innerexcept StopIteration:breakdef main():
g = outer_generator()
g.send(None)
i = 0
while 1:try:
i = g.send(i + 1)
print(i)except StopIteration:breakif __name__ == '__main__':
main()1234567891011121314151617181920212223242526272829303132333435363738394041
为了简化,在Python3.3中引入了yield from
yield from
使用yield from有两个好处,
1、可以将main中send的参数一直返回给最里层的generator , 
2、同时我们也不需要再使用while循环和send (), next()来进行迭代 。
我们可以将上边的代码修改如下:
def inner_generator():
i = 0
while True:
i = yield iif i10:raise StopIterationdef outer_generator():
print("do something before coroutine start")yield from inner_generator()def main():
g = outer_generator()
g.send(None)
i = 0
while 1:try:
i = g.send(i + 1)
print(i)except StopIteration:breakif __name__ == '__main__':
main()1234567891011121314151617181920212223242526
执行结果如下:
do something before coroutine start123456789101234567891011
这里inner_generator()中执行的代码片段我们实际就可以认为是协程,所以总的来说逻辑图如下:
接下来我们就看下究竟协程是啥样子
【异步函数python 异步函数有哪些】协程coroutine
协程的概念应该是从进程和线程演变而来的,他们都是独立的执行一段代码 , 但是不同是线程比进程要轻量级,协程比线程还要轻量级 。多线程在同一个进程中执行,而协程通常也是在一个线程当中执行 。它们的关系图如下:

推荐阅读