Python3推出好久了,其中的协程特性,一直没有时间来学习,这次跟着官方文档一起了解一下。
Python版本:3.6.6
import asyncio
async def hello_world():
print("Hello World!")
loop = asyncio.get_event_loop()
loop.run_until_complete(hello_world())
loop.close()
这里其实跟我们正常执行函数,没有很大的区别。
根据官方的介绍,这里的协程是通过一个task去做的,因此这里需要定义一个loop
,这个loop
会监听传入函数的执行状态。执行完毕之后,要把这个loop
给关掉。
其实Python3.8
改版成asyncio.run()
,这种方式其实是更友好的,基本上不感知协程的实现方式了。
import asyncio
async def slow_operation(future):
await asyncio.sleep(1)
future.set_result('Future is done!')
loop = asyncio.get_event_loop()
future = asyncio.Future()
asyncio.ensure_future(slow_operation(future))
loop.run_until_complete(future)
print(future.result())
loop.close()
可以看到,这里实际上是通过定义了一个Future
来实现的,在异步函数执行完毕之后,通过set_result
方法来设置结果。在外层就可以拿到这个结果。这种方式,可以按同步的思维来写异步的程序,并且获取返回结果。
import asyncio
async def slow_operation():
await asyncio.sleep(1)
return 'Future is done!'
def got_result(future):
print(future.result())
loop = asyncio.get_event_loop()
task = asyncio.ensure_future(slow_operation())
task.add_done_callback(got_result)
loop.run_until_complete(task)
loop.close()
这里的实例是我拿官方的实例修改的,更方便理解。这里的回调,会扔到一个Future
对象里面。通过这个对象的方法拿到结果。
import asyncio
import time
async def factorial(name, number):
f = 1
for i in range(2, number+1):
print("Task %s: Compute factorial(%s)..." % (name, i))
await asyncio.sleep(1)
f *= i
print("Task %s: factorial(%s) = %s" % (name, number, f))
loop = asyncio.get_event_loop()
print(time.time())
loop.run_until_complete(asyncio.gather(
factorial("A", 2),
factorial("B", 2),
factorial("C", 2),
))
print(time.time())
loop.close()
这里引入了一个gather
方法。同构这个方法,可以同时执行多个任务。
上面的代码我把官方的内容改了一下。执行结果可以看到。这三个任务实际上是同时执行的。整个函数执行耗时也只有1s。也就是实现了并发。
官方文档这里的实例,实际上是为了说明,loop会等待所有的任务执行完毕才结束。
A task is automatically scheduled for execution when it is created. The event loop stops when all tasks are done.
在看这个内容的时候,我一直在想,使用time.sleep(1)
和await asyncio.sleep(1)
有什么区别。
如果使用await的,协程遇到这部分就会切换上下文,如果不实用await的,就会一直阻塞。也就意味着,如果不实用await。。。并发就是个伪命题。
把上面的多任务执行实例中的await asyncio.sleep(1)
改成time.sleep(1)
。你会发现,这三个任务是串行的。
https://hackernoon.com/threaded-asynchronous-magic-and-how-to-wield-it-bba9ed602c32
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。