Python中asyncio库——线程并发函数的案例分析

  介绍

这篇文章主要介绍Python中asyncio库——线程并发函数的案例分析,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!

<强> asyncio——收集vs等

在asyncio中不止可以多次使用asyncio.gather,还有另外一个用法是asyncio。等等,他们都可以让多个协程并发执行。

 Python中asyncio库——线程并发函数的案例分析

那为什么提供2个方法呢?他们有什么区别,适用场景是怎么样的呢?我们先看2个协程的例子:

async  def  ():   ,,,print (& # 39; Suspending 一个# 39;)   ,,,await  asyncio.sleep (3)   ,,,print (& # 39; Resuming 一个# 39;)   ,,,return  & # 39;一个# 39;   async  def  b ():   ,,,print (& # 39; Suspending  b # 39;)   ,,,await  asyncio.sleep (1)   ,,,print (& # 39; Resuming  b # 39;)   ,,,return  & # 39; b # 39;

在IPython里面用收集执行一下:

拷贝:,return_value_a,, return_value_b =, await  asyncio.gather ((),, b ())   Suspending    Suspending  b   Resuming  b   Resuming    拷贝:return_value_a, return_value_b   :,(& # 39;一个# 39;,,& # 39;b # 39;)

好的,asyncio.gather方法的名字说明了它的用途,收集的意思是“搜集”,也就是能够收集协程的结果,而且要注意,它会按输入协程的顺序保存的对应协程的执行结果。

接着我们说asyncio。等待,先执行一下:

拷贝:,,,pending =, await  asyncio.wait (((),, b ()))   Suspending  b   Suspending    Resuming  b   Resuming    :拷贝完成   :   {& lt; Task  finished 重复=& lt;一个(),,,defined  at  & lt; ipython-input-5-5ee142734d16>: 1祝辞,结果=& # 39;一个# 39;祝辞,   ,& lt; Task  finished 重复=& lt; b (),,, defined  at  & lt; ipython-input-5-5ee142734d16>: 8祝辞,结果=& # 39;b # 39;祝辞}   拷贝:待定   :,设置()   拷贝:task (做)[0]=,列表   拷贝:任务   :,& lt; Task  finished 重复=& lt; b (),,, defined  at  & lt; ipython-input-5-5ee142734d16>: 8祝辞,结果=& # 39;b # 39;比;   拷贝:task.result ()   :,& # 39;b # 39;

asyncio.wait的返回值有2项,第一项表示完成的任务列表(完成),第二项表示等待(未来)完成的任务列表(待定),每个任务都是一个任务实例,由于这2个任务都已经完成,所以可以执行task.result()获得协程返回值。

好的,说到这里,总结下<强>它俩的区别的第一层区别:

asyncio.gather封装的任务全程黑盒,只告诉你协程结果。

asyncio.wait会返回封装的任务包(含已完成和挂起的任务),如果你关注协程执行结果你需要从对应的任务实例里面用结果方法自己拿。

为什么说“第一层区别”,asyncio.wait看名字可以理解为“等待”,所以返回值的第二项是等待列表,但是看上面的例子,等待是空集合,那么在什么情况下,等待里面不为空呢?这就是第二层区别:asyncio.wait支持选择返回的时机。

asyncio.wait支持一个接收参数return_when,在默认情况下,asyncio.wait会等待全部任务完成(return_when=& # 39; ALL_COMPLETED& # 39;),它还支持FIRST_COMPLETED(第一个协程完成就返回)和FIRST_EXCEPTION(出现第一个异常就返回):

拷贝:,,,pending =, await  asyncio.wait (((),, b ()),, return_when=asyncio.tasks.FIRST_COMPLETED)   Suspending    Suspending  b   Resuming  b   :拷贝完成   :,{& lt; Task  finished 重复=& lt; b (),,, defined  at  & lt; ipython-input-5-5ee142734d16>: 8祝辞,结果=& # 39;b # 39;祝辞}   拷贝:待定   :,{& lt; Task  pending 重复=& lt;一个(),running  at  & lt; ipython-input-5-5ee142734d16>: 3祝辞,wait_for=& lt; Future  pending  cb=[& lt; TaskWakeupMethWrapper  object  at  0 x108065e58>()]在祝辞}

看到了吧,这次只有协程b完成了,协程一个还是悬而未决的状态。

在大部分情况下,用asyncio.gather是足够的,如果你有特殊需求,可以选择asyncio.wait,举两个例子:

需要拿到封装好的任务,以便取消或者添加成功回调等

业务上需要FIRST_COMPLETED/FIRST_EXCEPTION即返回的

<强> asyncio。create_task vs循环。create_task vs asyncio。ensure_future

创建一个任务一共有3种方法,如这小节的标题。在上篇文章我说过,从Python 3.7开始可以统一的使用更高阶的asyncio.create_task。其实asyncio.create_task就是用的循环。create_task:

Python中asyncio库——线程并发函数的案例分析