首页 > 编程语言 >Python 异步: 常见问题 Part_1(23)

Python 异步: 常见问题 Part_1(23)

时间:2023-04-06 22:44:35浏览次数:42  
标签:... 常见问题 协程 Python tasks task 任务 Part asyncio

动动发财的小手,点个赞吧!

本节回答开发人员在 Python 中使用 asyncio 时提出的常见问题。

1. 如何停止任务?

我们可以通过 asyncio.Task 对象上的 cancel() 方法取消任务。如果任务被取消,cancel() 方法返回 True,否则返回 False。

...
# cancel the task
was_cancelled = task.cancel()

如果任务已经完成,则无法取消,cancel() 方法将返回 False,任务不会处于已取消状态。

下次任务有机会运行时,它将引发 CancelledError 异常。如果 CancelledError 异常未在包装协程内处理,任务将被取消。

否则,如果在包装协程内处理了 CancelledError 异常,任务将不会被取消。cancel() 方法还可以接受一个消息参数,该参数将在 CancelledError 的内容中使用。

我们可以探索如何取消正在运行的任务。

在这个例子中,我们定义了一个任务协程,它报告一条消息然后阻塞片刻。

然后我们定义用作 asyncio 程序入口点的主协程。它报告一条消息,创建并安排任务,然后等待片刻。

然后主协程在运行时恢复和取消任务。它再等一会儿,让任务响应取消请求。然后主协程报告取消任务的请求是否成功。

任务被取消,然后完成。主协程然后在关闭程序之前报告任务的状态是否已取消。

# SuperFastPython.com
# example of canceling a running task
import asyncio
 
# define a coroutine for a task
async def task_coroutine():
    # report a message
    print('executing the task')
    # block for a moment
    await asyncio.sleep(1)
 
# custom coroutine
async def main():
    # report a message
    print('main coroutine started')
    # create and schedule the task
    task = asyncio.create_task(task_coroutine())
    # wait a moment
    await asyncio.sleep(0.1)
    # cancel the task
    was_cancelled = task.cancel()
    # report whether the cancel request was successful
    print(f'was canceled: {was_cancelled}')
    # wait a moment
    await asyncio.sleep(0.1)
    # check the status of the task
    print(f'canceled: {task.cancelled()}')
    # report a final message
    print('main coroutine done')
 
# start the asyncio program
asyncio.run(main())

运行该示例会启动 asyncio 事件循环并执行 main() 协程。main() 协程报告一条消息,然后创建并调度任务协程。然后它暂停并等待片刻以允许任务协程开始运行。任务运行,报告消息并休眠一段时间。

main() 协程恢复和取消任务。它报告取消任务的请求已成功。然后它会休眠片刻,让任务响应要取消的请求。

task_coroutine() 恢复并引发 CancelledError 异常,导致任务失败并完成。main()协程恢复并报告任务是否处于取消状态。在这种情况下,确实如此。

此示例突出显示了取消正在运行的任务的正常情况。

main coroutine started
executing the task
was canceled: True
canceled: True
main coroutine done

2. 如何等待任务完成?

我们可以通过直接等待 asyncio.Task 对象来等待任务完成。

...
# wait for the task to finish
await task

我们可以在一行中创建和等待任务。

...
# create and wait for the task to finish
await asyncio.create_task(custom_coro())

3. 如何从任务中获取返回值?

我们可能需要将协程的值返回给调用者。我们可以通过等待从协程中检索返回值。它假定正在等待的另一个协程返回一个值。

# coroutine that returns a value
async def other_coro():
	return 100

等待其他协程将挂起调用协程并安排其他协程执行。一旦另一个协程完成,调用协程将恢复。返回值将从另一个协程传递给调用者。

...
# execute coroutine and retrieve return value
value = await other_coro()

协程可以包装在 asyncio.Task 对象中。这有助于独立执行协程而无需当前协程等待它。

这可以使用 asyncio.create_task() 函数来实现。

...
# wrap coroutine in a task and schedule it for execution
task = asyncio.create_task(other_coro())

有两种方法可以从 asyncio.Task 中检索返回值,它们是:

  • 等待任务。
  • 调用结果() 方法。

我们可以等待任务来检索返回值。如果任务已安排或正在运行,则调用者将挂起,直到任务完成并提供返回值。如果任务完成,将立即提供返回值。

...
# get the return value from a task
value = await task

与协程不同,我们可以多次等待任务而不会引发错误。

...
# get the return value from a task
value = await task
# get the return value from a task
value = await task

我们还可以通过调用 asyncio.Task 对象的 result() 方法来获取任务的返回值。

...
# get the return value from a task
value = task.result()

这需要完成任务。如果不是,将引发 InvalidStateError 异常。如果任务被取消,将引发 CancelledError 异常。

4. 如何在后台运行任务?

我们可以通过将协程包装在 asyncio.Task 对象中来在后台运行协程。这可以通过调用 asyncio.create_task() 函数并将其传递给协程来实现。

协程将被包装在一个 Task 对象中,并被安排执行。将返回任务对象,调用者不会挂起。

...
# schedule the task for execution
task = asyncio.create_task(other_coroutine())

至少在当前协程出于任何原因挂起之前,任务不会开始执行。我们可以通过暂停片刻让任务开始运行来帮助解决问题。这可以通过休眠零秒来实现。

...
# suspend for a moment to allow the task to start running
await asyncio.sleep(0)

这将暂停调用者一小会儿,并允许请求运行的机会。这不是必需的,因为调用者可能会在未来某个时间暂停或作为正常执行的一部分终止。一旦调用者没有事情要做,我们也可以直接等待任务。

...
# wait for the task to complete
await task

5. 如何等待所有后台任务?

我们可以等待 asyncio 程序中的所有独立任务。这可以通过首先通过 asyncio.all_tasks() 函数获取一组所有当前正在运行的任务来实现。

...
# get a set of all running tasks
all_tasks = asyncio.all_tasks()

这将返回一个集合,其中包含一个 asyncio.Task 对象,用于当前正在运行的每个任务,包括 main() 协程。

我们不能直接等待这个集合,因为它会永远阻塞,因为它包含当前任务。因此,我们可以获取当前正在运行的任务的 asyncio.Task 对象并将其从集合中删除。

这可以通过首先调用 asyncio.current_task() 方法来获取当前协程的任务,然后通过 remove() 方法将其从集合中删除来实现。

...
# get the current tasks
current_task = asyncio.current_task()
# remove the current task from the list of all tasks
all_tasks.remove(current_task)

最后,我们可以等待剩余的任务集。这将挂起调用者,直到集合中的所有任务都完成。

...
# suspend until all tasks are completed
await asyncio.wait(all_tasks)

将它们结合在一起,下面添加到 main() 协程末尾的代码片段将等待所有后台任务完成。

...
# get a set of all running tasks
all_tasks = asyncio.all_tasks()
# get the current tasks
current_task = asyncio.current_task()
# remove the current task from the list of all tasks
all_tasks.remove(current_task)
# suspend until all tasks are completed
await asyncio.wait(all_tasks)

本文由mdnice多平台发布

标签:...,常见问题,协程,Python,tasks,task,任务,Part,asyncio
From: https://www.cnblogs.com/swindler/p/17294492.html

相关文章

  • 每日总结2023/4/6(python实现分型图形设计)
    importrandomimportturtleturtle.speed(100)defke_line(line_,n):ifn==0:turtle.fd(line_)else:line_len=line_//3foriin[0,60,-120,60]:turtle.left(i)ke_line(line_len,n-1)#原始线......
  • Python + edge-tts:一行代码,让你的文本轻松变成语音!
    大家好,我是树先生!今天给大家介绍一个Python库edge-tts,可以在本地轻松将文本转换成语音,非常方便,并且完全免费!先来听一下效果:https://www.bilibili.com/audio/au3843189?type=1怎么样?是不是很熟悉,影视解说中常用开头:这个女人叫小美。。。 edge-tts介绍edge-tts是一个Py......
  • Python ORM Pony SQLite数据库 常用操作
    Pony是一个高级的对象关系映射器ORM框架。Pony它能够使用Python生成器表达式和lambdas向数据库编写查询。Pony分析表达式的抽象语法树,并将其转换为SQL查询。支持SQLite,MySQL,PostgreSQL和Oracle等数据库,本文主要介绍PythonORMPony中SQLite数据库常用操作,及数据增加、删除、修......
  • Python生成随机验证码
    pipinstallpillow 实现代码importrandomfromPILimportImage,ImageDraw,ImageFont,ImageFilterdefcheck_code(width=120,height=30,char_length=5,font_file='kumo.ttf',font_size=28):code=[]img=Image.new(mode='RGB',si......
  • Spartacus 4.0 升级到 5.0 后 checkout library 的设计变化
    在Spartacus4.0中,通过从原始storefront库中提取checkout功能,创建了一个新的checkoutlibrary实现。然而,这个新的库只有一个包含所有结帐流程的入口点,即使它们未被使用(例如scheduledreplenishmentflow)。但是,在Spartacus5.0中,checkout库已进一步分离为不同的业务逻......
  • 02:python-函数
     正文#1:调用内置函数#调用绝对值函数abs()intAbs=abs(-20)print(intAbs)#调用最大函数intMax=max(1,2,-1,10)print(intMax)#数据类型转换print(int('124'))#字符串转intprint(int(12.34))#float转intprint(str(12.34))#float转字符串......
  • Python小练习:权重初始化(Weight Initialization)
    Python小练习:权重初始化(WeightInitialization)作者:凯鲁嘎吉-博客园 http://www.cnblogs.com/kailugaji/调用Pytorch中的torch.nn.init.xxx实现对模型权重与偏置初始化。1.weight_init_test.py1#-*-coding:utf-8-*-2#Author:凯鲁嘎吉CoralGajic3#https://w......
  • 【转】python pip 换源阿里云
    via:pythonpip换源阿里云-知乎(zhihu.com)pip换源阿里云只需要在cmd输入一条命令:pipconfigsetglobal.index-urlhttps://mirrors.aliyun.com/pypi/simple ......
  • Spartacus 项目中的 facade 和 core 文件夹
    Spartacus是SAPCommerceCloud的storefront框架,feature-libs文件夹下的facade文件夹和core文件夹是Spartacus中用于实现特定功能的库文件夹。它们各自的作用如下:facade文件夹:存放与storefront框架中的各种功能和业务逻辑相关的代码。这些代码通过facade模式......
  • opencv-python 4.13. 霍夫线变换
    前言霍夫变换是一种特征检测(featureextraction),被广泛应用在图像分析(imageanalysis)、计算机视觉(computervision)以及数位影像处理(digitalimageprocessing)。霍夫变换(HoughTransform)是图像处理中的一种特征提取技术,它通过一种投票算法检测具有特定形状的物体。该过程......