Python 异步: 保护任务免于取消(13)

news/2024/3/29 17:54:37/文章来源:https://blog.csdn.net/swindler_ice/article/details/129251700

Asyncio 任务可以通过调用它们的 cancel() 方法来取消。我们可以通过将任务包装在对 asyncio.shield() 的调用中来保护任务不被取消。

让我们仔细看看。

1. 什么是 Asyncio shield()

asyncio.shield() 函数在 Future 中包装了一个可等待对象,它将吸收要取消的请求。

这意味着被屏蔽的未来可以传递给可能尝试取消它的任务,并且取消请求看起来像是成功的,除了被屏蔽的任务或协程将继续运行。

它可能在 asyncio 程序中很有用,其中某些任务可以取消,但其他任务(可能具有更高优先级)则不能。

它也可能在某些任务可以安全取消的程序中很有用,例如那些在设计时考虑了 asyncio 的任务,而其他任务则不能安全终止,因此必须避免取消。

现在我们知道了 asyncio.shield() 是什么,让我们看看如何使用它。

2. 如何使用 Asyncio shield()

asyncio.shield() 函数将保护另一个任务或协程不被取消。它以一个可等待对象作为参数并返回一个 asyncio.Future 对象。

然后可以直接等待 Future 对象或将其传递给另一个任务或协程。

...
# shield a task from cancellation
shielded = asyncio.shield(task)
# await the shielded task
await shielded

返回的 Future 可以通过调用 cancel() 方法取消。

如果内部任务正在运行,请求将被报告为成功。

...
# cancel a shielded task
was_canceld = shielded.cancel()

任何等待 Future 对象的协程都会引发 asyncio.CancelledError,这可能需要处理。

...
try:
 # await the shielded task
 await asyncio.shield(task)
except asyncio.CancelledError:
 # ...

重要的是,对 Future 对象的取消请求不会传播到内部任务。这意味着取消请求被护盾吸收了。

...
# create a task
task = asyncio.create_task(coro())
# create a shield
shield = asyncio.shield(task)
# cancel the shield (does not cancel the task)
shield.cancel()

如果协程被提供给 asyncio.shield() 函数,它将被包装在 asyncio.Task() 中并立即调度。

这意味着不需要等待屏蔽来让内部协程运行。

如果被屏蔽的任务被取消,取消请求将向上传播到屏蔽,屏蔽也将被取消。

...
# create a task
task = asyncio.create_task(coro())
# create a shield
shield = asyncio.shield(task)
# cancel the task (also cancels the shield)
task.cancel()

现在我们知道如何使用 asyncio.shield() 函数,让我们看一些有效的例子。

3. 示例

我们可以探索如何使用 asyncio.shield() 来保护任务不被取消。

在这个例子中,我们定义了一个简单的协程任务,它接受一个整数参数,休眠一秒钟,然后返回参数。然后可以创建协程并将其安排为任务。

我们可以定义第二个协程,它接受一个任务,休眠几分之一秒,然后取消提供的任务。

在主协程中,我们可以屏蔽第一个任务,然后将其传递给第二个任务,然后等待被屏蔽的任务。

期望是屏蔽将被取消并保持内部任务完好无损。取消将中断主协程。我们可以在程序结束时检查内部任务的状态,我们希望它已经正常完成,而不管屏蔽上的取消请求如何。

# SuperFastPython.com
# example of using asyncio shield to protect a task from cancellation
import asyncio
 
# define a simple asynchronous
async def simple_task(number):
    # block for a moment
    await asyncio.sleep(1)
    # return the argument
    return number
 
# cancel the given task after a moment
async def cancel_task(task):
    # block for a moment
    await asyncio.sleep(0.2)
    # cancel the task
    was_cancelled = task.cancel()
    print(f'cancelled: {was_cancelled}')
 
# define a simple coroutine
async def main():
    # create the coroutine
    coro = simple_task(1)
    # create a task
    task = asyncio.create_task(coro)
    # created the shielded task
    shielded = asyncio.shield(task)
    # create the task to cancel the previous task
    asyncio.create_task(cancel_task(shielded))
    # handle cancellation
    try:
        # await the shielded task
        result = await shielded
        # report the result
        print(f'>got: {result}')
    except asyncio.CancelledError:
        print('shielded was cancelled')
    # wait a moment
    await asyncio.sleep(1)
    # report the details of the tasks
    print(f'shielded: {shielded}')
    print(f'task: {task}')
 
# start
asyncio.run(main())

运行示例首先创建 main() 协程并将其用作应用程序的入口点。创建任务协程,然后将其包装并安排在任务中。然后该任务就不会被取消。

然后将屏蔽的任务传递给 cancel_task() 协程,该协程包装在任务中并进行调度。主协程然后等待受保护的任务,该任务需要 CancelledError 异常。

任务运行片刻然后休眠。取消任务运行片刻,休眠,恢复然后取消屏蔽任务。取消请求报告它已成功。

这会在受保护的 Future 中引发 CancelledError 异常,但不会在内部任务中引发。

main() 协程恢复并响应 CancelledError 异常,报告一条消息。然后它会睡一会儿。任务恢复、完成并返回一个值。

最后,main() 协程恢复,并报告被屏蔽的未来和内部任务的状态。我们可以看到屏蔽的未来被标记为已取消,而内部任务被标记为正常完成并提供返回值。

此示例突出显示了如何使用防护罩来成功保护内部任务不被取消。

cancelled: True
shielded was cancelled
shielded: <Future cancelled>
task: <Task finished name='Task-2' coro=<simple_task() done, defined at ...> result=1>

本文由 mdnice 多平台发布

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.luyixian.cn/news_show_75006.aspx

如若内容造成侵权/违法违规/事实不符,请联系dt猫网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【一】kubernetes集群部署

一、docker环境搭建 1、移除以前docker相关包 sudo yum remove docker docker-client docker-client-latest docker-common docker-latest docker-latest-logrotate docker-logrotate docker-engine2、配置yam源 sudo yum install -y yum-utilssudo yum-config-manager --ad…

C++进阶--二叉树编程题

文章目录力扣606. 根据二叉树创建字符串力扣102. 二叉树的层序遍历力扣236. 二叉树的最近公共祖先JZ36 二叉搜索树与双向链表力扣105--通过前序和中序遍历构造二叉树力扣144--二叉树的前序遍历&#xff08;非递归&#xff09;力扣94--二叉树的中序遍历&#xff08;非递归&#…

虹科新闻|虹科与iX systems正式建立合作伙伴关系

近日&#xff0c;虹科与美国iXsystems公司达成战略合作&#xff0c;虹科正式成为iXsystems公司在中国区域的认证授权代理商。未来&#xff0c;虹科将携手iXsystems&#xff0c;共同致力于提供企业级存储解决方案。虹科及iXsystems双方的高层领导人员都对彼此的合作有很大的信心…

操作系统基础教程

目录 第二章&#xff1a;处理器管理 概览 进程调度的层次 进程的调度方式&#xff1a; 调度的评价标准&#xff1a; 典型的调度算法&#xff1a; 第三章&#xff1a;同步、通信和死锁 什么是进程同步&#xff1f; 什么是进程互斥&#xff1f; 进程同步的实现方式 进程…

JVM总结

1. 内存结构 线程私有区 程序计算器 作用&#xff1a;是一块较小的内存空间&#xff0c;存储的是当前线程所执行的字节码文件的序号特点&#xff1a;线程私有&#xff0c;不会出现内存空间溢出 虚拟机栈 虚拟机栈是管理JAVA方法执行的内存模型&#xff0c;每个方法执行时都…

贴吧顶贴软件《今日/更新》

贴吧顶贴软件《今日/更新》百收贴吧工具箱&#xff0c;贴吧顶帖软件&#xff0c;贴吧推广引流神器#贴吧顶帖#贴吧推广 hello&#xff0c;大家好&#xff0c;我是软件的作者百收编辑狂潮老师。本次的视频讲解是作为一个百度顶贴的自动化脚本的视频安装教程和使用教程。你作为新…

SpringCloud(五)MQ消息队列

MQ概念常见消息模型helloworld案例实现实现spring AMQP发送消息实现spring AMQP接收消息工作消息队列实现发布订阅模型Fanout Exchange实现DirectExchange实现TopicExchange实现DirectExchange 和FanoutExchange的差异DirectExchange 和TopicExchange的差异基于RabbitListener注…

钉钉产品体验报告

一、调研的目的了解企业社交软件&#xff0c;借写竞品分析来帮助自己整理思路&#xff0c;看清市场的发展趋势&#xff1b;体验这类企业设计软件&#xff0c;掌握产品核心业务流程和产品结构&#xff0c;把握需求对应的功能点和界面结构&#xff0c;并侧面了解用户习惯&#xf…

用Python做数据分析有哪些优势?

众所周知&#xff0c;可以用作数据分析的语言有很多&#xff0c;包含Python、R语言等&#xff0c;而且Python被誉为数据分析的一大利器&#xff0c;更是该领域的首选语言&#xff0c;那么用Python做数据分析有哪些优势呢?跟着蛋糕往下看。 第一、Python语言自身的优势 Pytho…

ShardingSphere水平、垂直分库、分表和公共表

目录一、ShardingSphere简介二、ShardingSphere-分库分表1、垂直拆分&#xff08;1&#xff09;垂直分库&#xff08;2&#xff09;垂直分表2、水平拆分&#xff08;1&#xff09;水平分库&#xff08;2&#xff09;水平分表三、水平分库操作1、创建数据库和表2、配置分片的规则…

BigGAN

1、BIGGAN 解读1.1、作者 Andrew Brock、Jeff Donahue、Karen Simonyan 1.2、摘要 尽管最近在生成图像建模方面取得了进展&#xff0c;但从 ImageNet 等复杂数据集中 成功生成高分辨率、多样化的样本仍然是一个难以实现的目标。为此&#xff0c;我们以迄 今为止最大的规模训练生…

fastadmin:在新增页面,打开弹窗单选,参数回传

样式&#xff1a;核心代码&#xff1a;一、弹窗的控制器中&#xff1a;// 定义一个公共函数select()&#xff0c;如果这个请求是Ajax&#xff0c;则返回index()函数&#xff0c;否则返回view对象的fetch()函数。 public function select() {if ($this->request->isAjax(…

【软件测试】测试老鸟的迷途,进军高级自动化测试测试......

目录&#xff1a;导读前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结&#xff08;尾部小惊喜&#xff09;前言 很多从业几年的选手…

【阿旭机器学习实战】【37】电影推荐系统---基于矩阵分解

【阿旭机器学习实战】系列文章主要介绍机器学习的各种算法模型及其实战案例&#xff0c;欢迎点赞&#xff0c;关注共同学习交流。 电影推荐系统 目录电影推荐系统1. 问题介绍1.1推荐系统矩阵分解方法介绍1.2 数据集&#xff1a;ml-100k2. 推荐系统实现2.1 定义矩阵分解函数2.2 …

消息中间件的概念

中间件(middleware)是基础软件的一大类&#xff0c;属于可复用的软件范畴。中间件在操作系统软件&#xff0c;网络和数据库之上&#xff0c;应用软件之下&#xff0c;总的作用是为处于自己上层的应用软件提供运行于开发的环境&#xff0c;帮助用户灵活、高效的开发和集成复杂的…

ICA简介:独立成分分析

1. 简介 您是否曾经遇到过这样一种情况&#xff1a;您试图分析一个复杂且高度相关的数据集&#xff0c;却对信息量感到不知所措&#xff1f;这就是独立成分分析 (ICA) 的用武之地。ICA 是数据分析领域的一项强大技术&#xff0c;可让您分离和识别多元数据集中的底层独立来源。 …

PPP简介,PPP分层体系架构,PPP链路建立过程及PPP的帧格式

PPP&#xff08;Point-to-Point Protocol&#xff09;是一种用于在两个网络节点之间传输数据的通信协议。它最初是为在拨号网络上进行拨号连接而开发的&#xff0c;现在已经被广泛应用于各种网络环境中&#xff0c;例如在宽带接入、虚拟专用网&#xff08;VPN&#xff09;等场景…

【JAVA】一个项目如何预先加载数据?

这里写目录标题需求实现AutowiredPostConstruct实例CommandLineRunner实例ApplicationListener实例参考需求 一般我们可能会有一些在应用启动时加载资源的需求&#xff0c;局部或者全局使用&#xff0c;让我们来看看都有哪些方式实现。 实现 Autowired 如果是某个类里需求某…

[1]MyBatis+Spring+SpringMVC+SSM整合

一、MyBatis 1、MyBatis简介 1.1、MyBatis历史 MyBatis最初是Apache的一个开源项目iBatis, 2010年6月这个项目由Apache Software Foundation迁移到了Google Code。随着开发团队转投Google Code旗下&#xff0c; iBatis3.x正式更名为MyBatis。代码于2013年11月迁移到Github。…

Vue中如何利用websocket实现实时通讯

首先我们可以先做一个简单的例子来学习一下简单的websocket模拟聊天对话的功能 原理很简单&#xff0c;有点像VUE中的EventBus&#xff0c;用emit和on传来传去 首先我们可以先去自己去用node搭建一个本地服务器 步骤如下 1.新建一个app.js&#xff0c;然后创建pagejson.js文…