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

2024-03-24 20:20

本文主要是介绍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 密集型任务,异步编程并不能提升性能。

这篇关于CPU密集的高效访问和数据安全的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/842675

相关文章

轻松上手MYSQL之JSON函数实现高效数据查询与操作

《轻松上手MYSQL之JSON函数实现高效数据查询与操作》:本文主要介绍轻松上手MYSQL之JSON函数实现高效数据查询与操作的相关资料,MySQL提供了多个JSON函数,用于处理和查询JSON数... 目录一、jsON_EXTRACT 提取指定数据二、JSON_UNQUOTE 取消双引号三、JSON_KE

Tomcat高效部署与性能优化方式

《Tomcat高效部署与性能优化方式》本文介绍了如何高效部署Tomcat并进行性能优化,以确保Web应用的稳定运行和高效响应,高效部署包括环境准备、安装Tomcat、配置Tomcat、部署应用和启动T... 目录Tomcat高效部署与性能优化一、引言二、Tomcat高效部署三、Tomcat性能优化总结Tom

本地搭建DeepSeek-R1、WebUI的完整过程及访问

《本地搭建DeepSeek-R1、WebUI的完整过程及访问》:本文主要介绍本地搭建DeepSeek-R1、WebUI的完整过程及访问的相关资料,DeepSeek-R1是一个开源的人工智能平台,主... 目录背景       搭建准备基础概念搭建过程访问对话测试总结背景       最近几年,人工智能技术

Ollama整合open-webui的步骤及访问

《Ollama整合open-webui的步骤及访问》:本文主要介绍如何通过源码方式安装OpenWebUI,并详细说明了安装步骤、环境要求以及第一次使用时的账号注册和模型选择过程,需要的朋友可以参考... 目录安装环境要求步骤访问选择PjrIUE模型开始对话总结 安装官方安装地址:https://docs.

Python利用自带模块实现屏幕像素高效操作

《Python利用自带模块实现屏幕像素高效操作》这篇文章主要为大家详细介绍了Python如何利用自带模块实现屏幕像素高效操作,文中的示例代码讲解详,感兴趣的小伙伴可以跟随小编一起学习一下... 目录1、获取屏幕放缩比例2、获取屏幕指定坐标处像素颜色3、一个简单的使用案例4、总结1、获取屏幕放缩比例from

MySQL的cpu使用率100%的问题排查流程

《MySQL的cpu使用率100%的问题排查流程》线上mysql服务器经常性出现cpu使用率100%的告警,因此本文整理一下排查该问题的常规流程,文中通过代码示例讲解的非常详细,对大家的学习或工作有一... 目录1. 确认CPU占用来源2. 实时分析mysql活动3. 分析慢查询与执行计划4. 检查索引与表

解读静态资源访问static-locations和static-path-pattern

《解读静态资源访问static-locations和static-path-pattern》本文主要介绍了SpringBoot中静态资源的配置和访问方式,包括静态资源的默认前缀、默认地址、目录结构、访... 目录静态资源访问static-locations和static-path-pattern静态资源配置

使用Python实现高效的端口扫描器

《使用Python实现高效的端口扫描器》在网络安全领域,端口扫描是一项基本而重要的技能,通过端口扫描,可以发现目标主机上开放的服务和端口,这对于安全评估、渗透测试等有着不可忽视的作用,本文将介绍如何使... 目录1. 端口扫描的基本原理2. 使用python实现端口扫描2.1 安装必要的库2.2 编写端口扫

Oracle查询优化之高效实现仅查询前10条记录的方法与实践

《Oracle查询优化之高效实现仅查询前10条记录的方法与实践》:本文主要介绍Oracle查询优化之高效实现仅查询前10条记录的相关资料,包括使用ROWNUM、ROW_NUMBER()函数、FET... 目录1. 使用 ROWNUM 查询2. 使用 ROW_NUMBER() 函数3. 使用 FETCH FI

Java访问修饰符public、private、protected及默认访问权限详解

《Java访问修饰符public、private、protected及默认访问权限详解》:本文主要介绍Java访问修饰符public、private、protected及默认访问权限的相关资料,每... 目录前言1. public 访问修饰符特点:示例:适用场景:2. private 访问修饰符特点:示例: