栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 面试经验 > 面试问答

使用asyncio处理超时

面试问答 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

使用asyncio处理超时

选项1和2之间有实际区别吗?

否。选项2看起来更好,效率可能略高,但是它们的最终效果是相同的。

我知道

run_until_complete
它将一直运行到将来完成为止,所以由于选项1以特定的顺序循环,所以我认为如果较早的任务需要更长的时间才能完成,它的行为可能会有所不同。

一开始似乎是这样,但实际上并非如此,因为

loop.run_until_complete
运行提交到循环的 所有
任务,而不仅仅是运行作为参数传递的任务。它仅在提供的等待完成时 停止
-这就是“运行直到完成”的意思。调用
run_until_complete
已调度任务的循环类似于以下异步代码:

ts = [asyncio.create_task(asyncio.sleep(i)) for i in range(1, 11)]# takes 10s, not 55sfor t in ts:    await t

在语义上等效于以下线程代码:

ts = []for i in range(1, 11):    t = threading.Thread(target=time.sleep, args=(i,))    t.start()    ts.append(t)# takes 10s, not 55sfor t in ts:    t.join()

换句话说,

await t
run_until_complete(t)
块,直到
t
已完成,但让一切-
如使用先前计划的任务
asyncio.create_task()
在这段时间以及运行。因此,总运行时间将等于最长任务的运行时间,而不是总和。例如,如果第一个任务花费很长时间,那么所有其他任务都会在此期间完成,并且等待的对象根本无法入睡。

所有这些仅适用于先前已计划的等待任务。如果您尝试将其应用于协程,它将无法正常工作:

# runs for 55s, as expectedfor i in range(1, 11):    await asyncio.sleep(i)# also 55s - we didn't call create_task() so it's equivalent to the abovets = [asyncio.sleep(i) for i in range(1, 11)]for t in ts:    await t# also 55sfor i in range(1, 11):   t = threading.Thread(target=time.sleep, args=(i,))   t.start()   t.join()

这通常是asyncio初学者的症结所在,他们编写了与最后一个asyncio示例等效的代码,并期望它可以并行运行。

我尝试查看asyncio源代码以了解其在后台

asyncio.wait
的任务/功能是否有效地完成了同样的事情,但这并不明显。

asyncio.wait
只是一个方便的API,可完成两件事:

  • 将输入参数转换为实现的东西
    Future
    。对于协程,这意味着它将协程提交到事件循环,就像使用一样
    create_task
    ,这使它们可以独立运行。如果您像开始那样给它任务,那么将跳过此步骤。
  • 用于
    add_done_callback
    在期货交易完成时得到通知,届时它将恢复其呼叫者。

是的,它执行相同的操作,但是实现方式不同,因为它支持更多功能。

我认为,如果一项任务处于长时间运行的阻塞操作中间,它实际上可能不会立即取消吗?

在异步中,不应有“阻塞”操作,只有那些挂起的操作才应该被取消。例外是使用阻止附加到asyncio的代码

run_in_executor
,其中根本不会取消基础操作,但是asyncio协程将立即获取该异常。

也许这仅取决于所使用的基础操作或库是否会立即引发CancelledError?

库不 提高

CancelledError
,它在取消发生之前暂停的等待点 接收 它。对于图书馆而言,取消的效果是
await...
中断其等待并立即引发
CancelledError
。除非被捕获,否则异常将通过函数传播并一直
await
调用顶级协程,协程的提升
CancelledError
将整个任务标记为已取消。行为良好的异步代码将执行此操作,可能会
finally
用于释放它们持有的OS级资源。当
CancelledError
被捕获时,代码可以选择不重新引发它,在这种情况下,取消被有效地忽略了。

是否有可能loop.run_until_complete(或者实际上是对的基础调用

async.wait
)由于超时以外的原因而返回未完成的值?

如果您使用的

return_when=asyncio.ALL_COMPLETE
是默认设置,那是不可能的。使用很有可能
return_when=FIRST_COMPLETED
,然后显然有可能独立于超时。



转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/393678.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号