学习了三篇关于异步IO的文章:
(1) http://python.jobbole.com/87310/
(2) http://python.jobbole.com/87541/
(3) http://python.jobbole.com/88427/
整理一下学习心得:
1 # _*_ coding: utf-8 _*_ 2 import asyncio 3 import functools 4 5 6 async def do_some_work(x): 7 print("\033[;31mWaiting {}s\033[0m".format(str(x))) 8 await asyncio.sleep(x) 9 print("\033[;32mSleep {}s Done...\033[0m".format(str(x))) 10 return ‘Done after {}s‘.format(x) 11 12 13 def callback(future): 14 # 协程回调函数,需要 future 对象作为回调函数的最后一个参数。 15 # 通过future.result()可以获取协程执行的结果。 16 print("\033[;36mWaiting time {} ...\033[0m".format(future.result())) 17 18 19 def done_callback(loop, future): 20 # 协程回调函数 21 print("\033[;36mWaiting time {} ...\033[0m".format(future.result())) 22 loop.stop() # Add this line for run_forever_func 23 24 25 def run_until_complete_func(): 26 futu1 = asyncio.ensure_future(do_some_work(3)) # 将协程函数包装成 future 对象 27 futu1.add_done_callback(callback) # 为这个 future 对象添加回调函数,当协程函数运行完后会调用回调函数。 28 # add_done_callback只能接受一个回调函数作为参数,如果回调函数有参数,可以使用偏函数预处理回调函数。 29 30 futu2 = asyncio.ensure_future(do_some_work(1)) 31 futu2.add_done_callback(callback) 32 33 futus = [futu1, futu2] 34 loop = asyncio.get_event_loop() 35 # run_until_complete只接受单个 coroutine 或 future 对象作为参数; 36 # 但可以使用 asyncio.gather(*futures) 把多个future聚合包装成单个future; 37 # 也可以使用 asyncio.wait(futures),asyncio.wait() 方法接受一个task列表。 38 loop.run_until_complete(asyncio.gather(*futus)) # 或者:loop.run_until_complete(asyncio.wait(futus)) 39 loop.close() 40 41 42 def run_forever_func(): 43 loop = asyncio.get_event_loop() 44 45 futu1 = asyncio.ensure_future(do_some_work(1)) 46 futu2 = asyncio.ensure_future(do_some_work(3)) 47 futus = asyncio.gather(futu1, futu2) # 将两个 future 对象聚合成一个 future 对象 48 futus.add_done_callback(functools.partial(done_callback, loop)) # 为聚合后的新 future 对象添加回调函数 49 50 loop.run_forever() 51 loop.close() 52 53 54 async def coroutine_return(start_func): 55 coroutine1 = do_some_work(5) 56 coroutine2 = do_some_work(10) 57 coroutine3 = do_some_work(10) 58 tasks = [ 59 asyncio.ensure_future(coroutine1), 60 asyncio.ensure_future(coroutine2), 61 asyncio.ensure_future(coroutine3) 62 ] 63 if start_func == ‘wait‘: 64 return await asyncio.wait(tasks) 65 elif start_func == ‘gather‘: 66 return await asyncio.gather(*tasks) 67 elif start_func == ‘as_completed‘: 68 coroutine_results = [] 69 for task in asyncio.as_completed(tasks): 70 result = await task # 获取协程函数的返回值 71 coroutine_results.append(result) 72 return coroutine_results 73 74 # 【聚合后的协程函数的返回值】 75 # (1) 如果使用asyncio.gather创建协程对象,那么使用await挂起的有阻塞的协程,它们的返回值就是协程运行的结果。 76 # (2) 如果使用asyncio.wait创建协程对象,那么使用await挂起的有阻塞的协程,它们的返回值是一个两个元素的元组, 77 # 元组第一个元素是finished状态的所有协程对象的集合,第二个元素目前来看是一个空的集合。 78 # (3) 还可以使用asyncio.as_completed创建协程对象,但是这个方法和以上两个方法略有不同, 79 # 这个方法返回一个生成器,生成器的元素是单个协程对象,然后再通过循环并使用await启动各个协程函数。 80 # (4) run_until_complete函数可以理解为仅仅是驱动event_loop,而不会影响作为它参数的协程对象。 81 # 即它的返回值就是作为它参数的协程函数的返回值。 82 # (5) 当所有的协程对象都是finished状态时,才会返回。 83 84 85 def coroutine_return_done(start_func): 86 loop = asyncio.get_event_loop() 87 if start_func == ‘wait‘: 88 result, pending = loop.run_until_complete(coroutine_return(start_func)) 89 elif start_func == ‘gather‘: 90 result = loop.run_until_complete(coroutine_return(start_func)) 91 elif start_func == ‘as_completed‘: 92 result = loop.run_until_complete(coroutine_return(start_func)) 93 else: 94 result = ‘coroutine not start...‘ 95 print(result) 96 97 98 if __name__ == ‘__main__‘: 99 run_until_complete_func() 100 # run_forever_func() 101 # coroutine_return_done(‘as_completed‘)
未完待续。。。
原文地址:https://www.cnblogs.com/Oliver-yzx/p/10310723.html
时间: 2024-11-14 12:35:38