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

相关文章

C#使用SQLite进行大数据量高效处理的代码示例

《C#使用SQLite进行大数据量高效处理的代码示例》在软件开发中,高效处理大数据量是一个常见且具有挑战性的任务,SQLite因其零配置、嵌入式、跨平台的特性,成为许多开发者的首选数据库,本文将深入探... 目录前言准备工作数据实体核心技术批量插入:从乌龟到猎豹的蜕变分页查询:加载百万数据异步处理:拒绝界面

Spring Boot + MyBatis Plus 高效开发实战从入门到进阶优化(推荐)

《SpringBoot+MyBatisPlus高效开发实战从入门到进阶优化(推荐)》本文将详细介绍SpringBoot+MyBatisPlus的完整开发流程,并深入剖析分页查询、批量操作、动... 目录Spring Boot + MyBATis Plus 高效开发实战:从入门到进阶优化1. MyBatis

SpringBoot使用OkHttp完成高效网络请求详解

《SpringBoot使用OkHttp完成高效网络请求详解》OkHttp是一个高效的HTTP客户端,支持同步和异步请求,且具备自动处理cookie、缓存和连接池等高级功能,下面我们来看看SpringB... 目录一、OkHttp 简介二、在 Spring Boot 中集成 OkHttp三、封装 OkHttp

使用Python高效获取网络数据的操作指南

《使用Python高效获取网络数据的操作指南》网络爬虫是一种自动化程序,用于访问和提取网站上的数据,Python是进行网络爬虫开发的理想语言,拥有丰富的库和工具,使得编写和维护爬虫变得简单高效,本文将... 目录网络爬虫的基本概念常用库介绍安装库Requests和BeautifulSoup爬虫开发发送请求解

使用Dify访问mysql数据库详细代码示例

《使用Dify访问mysql数据库详细代码示例》:本文主要介绍使用Dify访问mysql数据库的相关资料,并详细讲解了如何在本地搭建数据库访问服务,使用ngrok暴露到公网,并创建知识库、数据库访... 1、在本地搭建数据库访问的服务,并使用ngrok暴露到公网。#sql_tools.pyfrom

Android如何获取当前CPU频率和占用率

《Android如何获取当前CPU频率和占用率》最近在优化App的性能,需要获取当前CPU视频频率和占用率,所以本文小编就来和大家总结一下如何在Android中获取当前CPU频率和占用率吧... 最近在优化 App 的性能,需要获取当前 CPU视频频率和占用率,通过查询资料,大致思路如下:目前没有标准的

Javascript访问Promise对象返回值的操作方法

《Javascript访问Promise对象返回值的操作方法》这篇文章介绍了如何在JavaScript中使用Promise对象来处理异步操作,通过使用fetch()方法和Promise对象,我们可以从... 目录在Javascript中,什么是Promise1- then() 链式操作2- 在之后的代码中使

如何使用Docker部署FTP和Nginx并通过HTTP访问FTP里的文件

《如何使用Docker部署FTP和Nginx并通过HTTP访问FTP里的文件》本文介绍了如何使用Docker部署FTP服务器和Nginx,并通过HTTP访问FTP中的文件,通过将FTP数据目录挂载到N... 目录docker部署FTP和Nginx并通过HTTP访问FTP里的文件1. 部署 FTP 服务器 (

Go使用pprof进行CPU,内存和阻塞情况分析

《Go使用pprof进行CPU,内存和阻塞情况分析》Go语言提供了强大的pprof工具,用于分析CPU、内存、Goroutine阻塞等性能问题,帮助开发者优化程序,提高运行效率,下面我们就来深入了解下... 目录1. pprof 介绍2. 快速上手:启用 pprof3. CPU Profiling:分析 C

C++实现回文串判断的两种高效方法

《C++实现回文串判断的两种高效方法》文章介绍了两种判断回文串的方法:解法一通过创建新字符串来处理,解法二在原字符串上直接筛选判断,两种方法都使用了双指针法,文中通过代码示例讲解的非常详细,需要的朋友... 目录一、问题描述示例二、解法一:将字母数字连接到新的 string思路代码实现代码解释复杂度分析三、