对于来自JavaScript编码者来说,异步编程不是什么新东西,但对于Python开发者来说,async函数和future(类似JS的promise)可不是那么容易能理解的。
Concurrency vs Parallelism
Concurrency和Parallelism听起来一样,但在实际编程里它们有着较大的不同。
想象下你在做饭的时候写书,看起来好像你在同一时间做两件事情,实际你只是在两项事情中相互切换,当你在等水开的时候你就可以去写书,但你切菜时你要暂停写作。这就叫做concurrency。唯一一种使用parallel做这两项工作的办法就是得有两个人,一个人写作,一个人做饭,这就是多核CPU的工作方式了。
为什么asyncio
异步编程允许你在单个线程中并发执行代码。对比多线程处理方式,该方式由你来决定如何由一个任务切换到另一个任务,tasks之间共享数据也更加容易和简单。
def queue_push_back(x):
if len(list) < max_size:
list.append(x)
如果我们在多线程执行上面的额代码,有可能第二行代码在同一时间被执行,那么同一时间就有两个元素被加入到列表中,那实际列表长度就会操作max_size。
另一个异步编程的好处是内存使用。每次一个新的线程创建,也需要开辟一些新内存用来进行上下文切换。如果使用了异步编程,这在单线程中就不存在该问题。
如何在Python编程async代码
Asyncio包含三个主要组件:coroutine, event loop和future
Coroutine
coroutine是异步函数,通过在函数定义def前使用async关键字。
async def my_task(args):
pass
my_coroutine = my_task(args)
我们使用了async关键字定义了一个函数,该函数并没有执行,返回了一个coroutine对象。
有两种从一个coroutine中获取异步函数的结果
第一种使用await关键字,仅只能在async函数中用来等待coroutine结束返回结果
result = await my_task(args)
第二种是将它加入到event loop中,接下来我们做详尽讨论。