CPU密集的高效访问和数据安全

import asyncio
import concurrent.futures
import random

# 全局变量,用于存储计算结果的列表
list1 = []
list2 = []
lock = asyncio.Lock()  # 异步锁

# CPU计算密集型任务
async def cpu_intensive_task():
    global list1, list2

    # 获取异步锁
    async with lock:
        # 进行CPU计算密集型任务,这里简单地生成随机数并添加到列表中
        random_number = random.randint(1, 100)
        list1.append(random_number)
        list2.append(random_number * 2)

# 读取协程函数
async def reader_coroutine():
    global list1, list2

    while True:
        # 获取异步锁
        async with lock:
            # 读取列表1和列表2的值
            print(f"List 1: {list1}")
            print(f"List 2: {list2}")
        await asyncio.sleep(1)  # 每隔1秒读取一次

# 创建事件循环对象
loop = asyncio.get_event_loop()

# 创建多个读取协程并添加到事件循环中
readers = [reader_coroutine() for _ in range(5)]  # 创建5个读取协程

# 同时执行CPU计算密集型任务和读取协程
tasks = [cpu_intensive_task(), *readers]
loop.run_until_complete(asyncio.gather(*tasks))

# 关闭事件循环
loop.close()

上面的cpu_intensive_task 函数是CPU密集型,里面没有await和IO操作,就只有这个函数里修改两个全局变量list1和list2,其他协程函数都是读取。根据我们上面的总结,也就是我们可以不用加锁,也不会导致其他协程任务读到的数据两个全局变量list1和list2的数据不一致问题吗?

是的,根据我们之前的讨论和总结,如果 cpu_intensive_task 函数是一个纯粹的 CPU 密集型任务,没有涉及到 IO 操作或者 await 表达式,而且只是修改两个全局变量 list1list2,那么在这种情况下,可以不用加锁。

因为在 Python 中的 GIL(全局解释器锁)机制下,对于 CPU 密集型任务,即使有多个线程或者协程在执行,它们也无法同时访问同一个 CPU 核心,因此不会出现多个协程同时修改全局变量导致数据不一致的问题。

所以,在你的情况下,cpu_intensive_task 函数只是修改两个全局变量 list1list2,而其他协程函数只是读取这两个全局变量的值,因此不需要加锁也不会导致数据不一致的问题

那如果cpu_intensive_task 这个异步函数里有一部分存在读取文件,但是这个函数里面都没有使用await关键字或者有await关键字但await不会出现在修改两个全局变量list1和list2的中间位置,还是可以不用加锁吗?

在你描述的情况下,即使 cpu_intensive_task 函数中包含了一部分读取文件的操作,但没有使用 await 关键字或者 await 关键字不会出现在修改全局变量 list1list2 的中间位置,依然可以不用加锁。

异步编程中,如果一个协程内部有 IO 操作,但是这些 IO 操作不是通过 await 关键字等待的话,不会触发协程的挂起,也不会引起事件循环的切换。因此,只有涉及到 await 表达式才会触发挂起和事件循环的切换。

所以,在你的情况下,即使 cpu_intensive_task 函数中包含了一部分读取文件的操作,只要这些 IO 操作没有使用 await 等待,并且 await 关键字不会出现在修改全局变量 list1list2 的中间位置,依然可以不用加锁。

上面的cpu_intensive_task 这个异步函数里面await关键字 如果等待的是一个计算密集型任务,CPU在执行到这个await时不会让渡出CPU资源,只会阻塞等待任务的执行然后继续执行下面的代码吗?

对于异步函数中使用 await 关键字等待的是一个计算密集型任务,情况会有些不同。Python 中的异步机制实际上是基于事件循环的协作式调度,当遇到 await 表达式时,如果等待的是一个计算密集型任务(例如在同一个线程内的一些 CPU 密集型操作),那么 await 表达式会阻塞当前协程并暂时放弃 CPU 控制权,而不是等待任务的执行然后继续执行下面的代码。

这是因为在 Python 中,GIL(全局解释器锁)的存在导致了对于 CPU 密集型任务的并行执行无法真正实现。当一个协程遇到 await 表达式等待一个 CPU 密集型任务时,事件循环实际上会挂起这个协程,然后切换到其他就绪状态的协程执行。这样可以在遇到长时间的 CPU 计算时,避免整个事件循环被阻塞,提高了程序的并发性能。

所以,总的来说,异步函数中 await 关键字等待的是一个计算密集型任务时,不会让出 CPU 资源,而是暂时放弃 CPU 控制权,让事件循环调度其他协程执行,然后等待任务完成后再继续执行下面的代码。

也就是CPU遇到await关键字不管后面是否是CPU密集型任务还是IO任务都会暂时放弃当前任务的控制权,转而执行其他待续任务,而当执行awai后面的CPU密集任务时,CPU并不会任意切换到其他任务中?

是的,你的理解基本上是正确的。

在 Python 中,遇到 await 关键字时,不管后面是 CPU 密集型任务还是 IO 密集型任务,当前协程都会暂时放弃 CPU 控制权,转而执行其他待续任务,让事件循环调度其他协程执行。这是异步编程中的协作式调度机制,目的是避免阻塞整个事件循环。

当执行到 await 后面的 CPU 密集型任务时,因为 Python 中的 GIL(全局解释器锁)的存在,任务并不会真正实现并行执行,而是仍然在单个 CPU 核心上执行。但是由于事件循环的调度机制,当前协程会暂时放弃 CPU 控制权,让事件循环调度其他协程执行。这样可以避免一个长时间的 CPU 密集型任务阻塞整个事件循环,提高了程序的并发性能。

You

你的意思是当执行到 await 后面的 CPU 密集型任务里面时,CPU随时都可能让渡出计算资源转而执行其他任务里的代码?

不完全正确。在 Python 中,对于 CPU 密集型任务,当执行到 await 后面的 CPU 密集型任务时,CPU 不会随时让渡出计算资源转而执行其他任务里的代码。在单个线程内,CPU 密集型任务的执行会一直占用 CPU 资源,直到任务执行完成才会继续执行其他任务。

具体来说,当一个协程遇到 await 表达式等待一个 CPU 密集型任务时,该协程会暂时挂起,让出 CPU 控制权,但并不会让渡出计算资源,因为 Python 中的 GIL(全局解释器锁)的存在导致在单个线程内只能有一个线程执行 Python 字节码。因此,即使事件循环切换到其他协程,CPU 仍然会继续执行当前 CPU 密集型任务,直到任务执行完成或者遇到 IO 操作或者 await 关键字等待其他协程。

总之,CPU 密集型任务的执行不会随时让渡出计算资源转而执行其他任务里的代码,而是会一直执行直到完成或者遇到挂起条件。异步编程中的优势主要体现在 IO 密集型任务的异步执行上,对于 CPU 密集型任务,异步编程并不能提升性能。

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

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

相关文章

Excel通过下拉菜单,显示不同图片

背景:有的时候需要通过更改下拉菜单来改变对应的 值/ 图片。 如果是数值的话就是我们常常用的Vlookup,这个可以很简单的实现这个功能。(这个如果不知道请自行百度) 但是如果是图片呢?这个就不常见了,那么…

Unity中关于SendMessage方法

在Unity中,SendMessage 方法用于在游戏对象及其所有子对象上调用指定名称的方法。这种方法可以用于在不需要知道接收方的确切类型的情况下,向游戏对象发送消息。 基本语法如下: void SendMessage(string methodName, object value null, S…

机器学习:随机森林算法

随机森林算法 决策树与随机森林随机森林 决策树与随机森林 随机森林可以看作一个决策树的集合,由n个子训练集得到的决策树组成。 决策树(Decision tree)是一种特殊的树结构,由一个决策图和可能的结果(例如成本和风险…

java使用socket实现一个简单的聊天室

1. 服务端 import java.io.IOException; import java.net.ServerSocket; import java.net.Socket; import java.util.ArrayList; import java.util.List;public class ChatServer {private static final int PORT 8070;private static List<ClientHandler> clients ne…

芯片工程系列(5)2.5D 3D封装

0 英语缩写 硅通孔&#xff08;Through Silicon Via&#xff0c;TSV&#xff09;硅中介层&#xff08;Silicon Interposer&#xff09;物理气象沉淀法&#xff08;Physical Vapor Deposition&#xff0c;PVD&#xff09;DRIE、CVD、PVD、CMP等设备CoWoS&#xff08;Chip on Wa…

【开发环境搭建篇】Nacos的安装和配置

作者介绍&#xff1a;本人笔名姑苏老陈&#xff0c;从事JAVA开发工作十多年了&#xff0c;带过大学刚毕业的实习生&#xff0c;也带过技术团队。最近有个朋友的表弟&#xff0c;马上要大学毕业了&#xff0c;想从事JAVA开发工作&#xff0c;但不知道从何处入手。于是&#xff0…

利用K8S Statefulset搭建Etcd集群 - 本地存储

目录 概述测试环境yaml配置service.yamlcluster.yaml Q&A参考链接 概述 公司因项目需要使用K8S部署ETCD集群供其他业务调用&#xff0c;网上搜索了解了下&#xff0c;一般K8S搭建ETCD集群大部分都是使用Etcd Operator来搭建。但是公司的项目运行在离线ARM架构平台&#xf…

安卓手机系统跳过app启动广告软件

跳过广告关于此应用声明&#xff1a; 应用利用了安卓系统的辅助功能API&#xff0c;可以读取您手机屏幕上显示的所有内容&#xff0c;并且可以以您的名义进行屏幕点击等操作。* 轻量无广告&#xff0c;不联网&#xff0c;也不需要任何权限&#xff1b;* 请务必在系统设置中开启…

【C++】分球

题目描述 7个人分球&#xff0c;共有n个球&#xff0c;所有人得到的球必须相等。请输出最少剩下的球数。 输入 输入一行一个正整数n&#xff08;可能存在前导零&#xff09;。 输出 输出一行一个整数&#xff0c;如题所述答案。 样例输入 Copy 50样例输出 Copy 1提示 …

Redis中AOF、RDB和复制功能对过期键的处理

AOF、RDB和复制功能对过期键的处理 生成RDB文件 在执行SAVE命令或者BGSAVE命令创建一个新的RDB文件时&#xff0c;程序会对数据库中的键进行检查&#xff0c;已过期的键不会被保存到新创建的RDB文件中。 例子 举个例子&#xff0c;如果数据库中包含三个键k1、k2、k3&#x…

【目标检测实验系列】AutoDL线上GPU服务器租用流程以及如何用Pycharm软件远程连接服务器进行模型训练 (以Pycharm远程训练Yolov5项目为例子 超详细)

目录 1. 文章主要内容2. 租用AutoDL服务器详细教程2.1 注册AutoDL账号&#xff0c;并申请学生认证(学生认证有优惠&#xff0c;如果不是学生可以忽略此点)2.2 算力市场选择GPU&#xff0c;并选择初始化配置环境2.3 控制台参数解析&#xff0c;并使用相关参数登录Xftp(Windows与…

LangChain核心模块 Retrieval——文本分割

Text Splitters 文本分隔 检索的关键部分时仅获取文档的相关部分&#xff0c;主要任务之一是将大文档分割为更小的块。 最简单的例子是&#xff0c;将长文档分割成更小的块&#xff0c;以适合模型的上下文窗口。 LangChain 有许多内置的文档转换器&#xff0c;可以轻松地拆…

Office办公软件之word的使用(一)

前几天调整公司招标文件的格式&#xff0c;中途遇到一些问题&#xff0c;感觉自己还不是太熟悉操作&#xff0c;通过查阅资料&#xff0c;知道了正确的操作&#xff0c;就想着给记下来。如果再次遇到&#xff0c;也能很快地找到解决办法。 一、怎么把标题前的黑点去掉 解决办法…

[ C++ ] STL---list的模拟实现

目录 结点类的模拟实现 迭代器类的模拟实现 构造函数 前置与后置 前置- -与后置 - - 与 !运算符重载 * 运算符重载 -> 运算符重载 普通迭代器总体实现代码 list类的实现 list类的成员变量 构造函数 迭代器 insert(&#xff09; erase() push_front/push_back…

Qt-QDialog非模态置于窗口之上且操作主窗口不隐藏dialog的方法

方法为&#xff1a; QDialog* dialog new QDialog; dialog->setParent(this, dialog->windowFlags()); dialog->show(); dialog->raise();QDialog继承自QWidget&#xff0c;setParent方法会重置其windowFlags&#xff0c;因此我们将其原始windowFlags传入作为参数…

ffmpeg/ffplay指令

ffplay 1、音频 (1)、播放PCM文件: ffplay -ar 8000 -ac 1 -f s16le input.pcm -ar 8000 设置采样率为8000 Hz。 -ac 1 设置声道数为1&#xff08;单声道&#xff09;。 -f s16le 指定音频格式为16位小端有符号整数&#xff08;PCM&#xff09; (2)、播放G.711 a-law文件: …

英语10大词性

英文缩写v 代表动词 对应的英单词是verb 音标 英[vɜːb] 美[vɜːrb] 英文缩写n 代表名词 对应的英文单词是noun 音标 英[naʊn] 美[naʊn] 英文缩写prep 代表介词 对应的英文单词是preposition 音标 英[ˌprepəˈzɪʃn…

【SQL】1527. 患某种疾病的患者(like;通配符)

前述 知识点回顾&#xff1a; MySQL 使用OR在LIKE查询中比较多个字段 %&#xff1a;表示任意字符&#xff08;包括0个或多个&#xff09;_&#xff1a;表示任意单个字符匹配空格&#xff1a;直接用空格就行&#xff0c;例如&#xff0c;% DIAB1%可以匹配字符串ACNE DIAB100 …

非插件方式为wordpress添加一个额外的编辑器

在WordPress中&#xff0c;要添加一个额外的区块编辑器(通常指的是Gutenberg区块编辑器中的一个自定义区块)&#xff0c;你需要编写一些PHP代码来注册新的区块&#xff0c;并可能还需要一些JavaScript来处理前端的逻辑。下面是一个简单的示例&#xff0c;展示了如何注册一个自定…

Python Flask框架 -- ORM模型与表的映射

ORM模型 对象关系映射(Object Relationship Mapping)&#xff0c;简称ORM&#xff0c;是一种可以用Python面向对象的方式来操作关系型数据库的技术&#xff0c;具有可以映射到数据库表能力的Python类我们称之为ORM模型。一个ORM模型与数据库中一个表相对应&#xff0c;ORM模型中…