Python的共享内存、共享内存队列

共享内存是自python3.8开始引入的新功能。

1. 共享内存 – multiprocessing.shared_memory

multiprocessing.shared_memory — 可跨进程直接访问的共享内存,是从python3.8 开始引入的功能。

该模块提供了一个 SharedMemory 类,用于分配和管理多核或对称多处理器(SMP)机器上进程间的共享内存。为了协助管理不同进程间的共享内存生命周期,multiprocessing.managers 模块也提供了一个 BaseManager 的子类: SharedMemoryManager

本模块中,共享内存是指 “System V 类型” 的共享内存块(虽然可能和它实现方式不完全一致)而不是 “分布式共享内存”。这种类型的的共享内存允许不同进程读写一片公共(或者共享)的易失性存储区域。一般来说,进程被限制只能访问属于自己进程空间的内存,但是共享内存允许跨进程共享数据,从而避免通过进程间发送消息的形式传递数据。相比通过磁盘、套接字或者其他要求序列化、反序列化和复制数据的共享形式,直接通过内存共享数据拥有更出色性能。

class multiprocessing.shared_memory.SharedMemory(name=None, create=False, size=0)

创建一个新的共享内存块或者连接到一片已经存在的共享内存块。每个共享内存块都被指定了一个全局唯一的名称。通过这种方式,一个进程可以通过提供一个特定的名字创建一个共享内存区块,然后其他进程使用同样的名字连接到这个共享内存块。

作为一种跨进程共享数据的方式,共享内存块的寿命可能超过创建它的原始进程。一个共享内存块可能同时被多个进程使用,当一个进程不再需要访问这个共享内存块的时候,应该调用 close() 方法。当一个共享内存块不被任何进程使用的时候,应该调用 unlink() 方法以执行必要的清理。

name 是共享内存的唯一名称,字符串类型。如果创建一个新共享内存块的时候,名称指定为 None (默认值),将会随机产生一个新名称。

create 指定创建一个新的共享内存块 (True) 还是连接到已存在的共享内存块 (False) 。

如果是新创建共享内存块则 size 用于指定块的大小为多少字节。由于某些平台是使用特定内存页大小为最小单位来分配的,最终得到的内存块大小可能大于或等于要求的大小。如果是连接到已经存在的共享内存块, size 参数会被忽略。

  • close()

    关闭实例对于共享内存的访问连接。所有实例确认自己不再需要使用共享内存的时候都应该调用 close() ,以保证必要的资源清理。调用 close() 并不会销毁共享内存区域。

  • unlink()

    请求销毁底层的共享内存块。 为了执行必要的资源清理,在所有使用这个共享内存块的进程中,unlink() 应该调用一次(且只能调用一次)。 发出此销毁请求后,共享内存块可能会、也可能不会立即销毁,且此行为在不同操作系统之间可能不同。 调用 unlink() 后再尝试访问其中的数据可能导致内存错误。 注意:最后一个关闭共享内存访问权限的进程可以以任意顺序调用 unlink()close()

  • buf

    共享内存块内容的 memoryview 。

  • name

    共享内存块的唯一标识,只读属性。

  • size

    共享内存块的字节大小,只读属性。

示例1:展示了 SharedMemory 的基础用法

from multiprocessing import shared_memory
import arrayif __name__ == '__main__':shm_a = shared_memory.SharedMemory(create=True, size=40)print('type: ', type(shm_a))print('name: ', shm_a.name)print('size: ', shm_a.size)buffer = shm_a.bufbuffer[:4] = bytearray([22, 33, 44, 55])  # Modify multiple at onceprint('buffer_a: ', [i for i in bytes(buffer[:4])])buffer[4] = 100                           # Modify single byte at a timeprint('buffer_a: ', [i for i in bytes(buffer[:5])])shm_b = shared_memory.SharedMemory(shm_a.name)shm_b_array = array.array('b', shm_b.buf[:5])   # Copy the data into a new array.arrayprint('shm_b_array: ', shm_b_array)shm_b.buf[:5] = b'howdy'    # Modify via shm_b using bytesprint('buffer_a: ', bytes(shm_b.buf[:5]))   # Access via shm_ashm_b.close()   # Close each SharedMemory instanceshm_a.close()shm_a.unlink()  # Call unlink only once to release the shared memory

输出:

type:  <class 'multiprocessing.shared_memory.SharedMemory'>
name:  wnsm_97359521
size:  40
buffer_a:  [22, 33, 44, 55]
buffer_a:  [22, 33, 44, 55, 100]
shm_b_array:  array('b', [22, 33, 44, 55, 100])
buffer_a:  b'howdy'

示例2:展示了 SharedMemory类结合NumPy 数组的读写示例

import multiprocessing
import time
from multiprocessing import shared_memory
import numpy as npclass ChildProcess(multiprocessing.Process):def __init__(self, shm_name=None, shape=None, dtype=None):super().__init__()self._shm_name = shm_nameself._shape = shapeself._dtype = dtypedef run(self) -> None:existing_shm = shared_memory.SharedMemory(name=self._shm_name, create=False)    # Attach to the existing shared memory blockprint(existing_shm.name)c = np.ndarray(shape=self._shape, dtype=self._dtype, buffer=existing_shm.buf)print('c0: ', c)c[-1] = 888print('c1: ', c)del cexisting_shm.close()if __name__ == '__main__':a = np.array([1, 1, 2, 3, 5, 6])    # Start with an existing NumPy arrayprint('a: ', a)print('a.shape: ', a.shape)print('a type: ', type(a))shm = shared_memory.SharedMemory(name=None, create=True, size=a.nbytes)b = np.ndarray(a.shape, dtype=a.dtype, buffer=shm.buf)  # Now create a NumPy array backed by shared memoryprint('b0: ', b)b[:] = a[:]     # Copy the original data into shared memoryprint('b1: ', b)print('shm name: ', shm.name)child_process = ChildProcess(shm_name=shm.name, shape=b.shape, dtype=b.dtype)child_process.start()time.sleep(2)print('b2: ', b)shm.close()shm.unlink()    # Free and release the shared memory block at the very end

输出:

a:  [1 1 2 3 5 6]
a.shape:  (6,)
a type:  <class 'numpy.ndarray'>
b0:  [0 0 0 0 0 0]
b1:  [1 1 2 3 5 6]
shm name:  wnsm_cb62400b
wnsm_cb62400b
c0:  [1 1 2 3 5 6]
c1:  [  1   1   2   3   5 888]
b2:  [  1   1   2   3   5 888]

示例3:展示了 SharedMemory类结合NumPy 图像的示例

from multiprocessing import shared_memory
import numpy as np
import cv2if __name__ == '__main__':image = cv2.imread('1.jpg')print(type(image))print(image.shape)image_shape = image.shapeimage_dtype = image.dtypeshm = shared_memory.SharedMemory(name=None, create=True, size=2448*2048*3*1)	# 图像像素2448x2048, RGB 3通道shm_ndarray = np.ndarray(shape=image_shape, dtype=image_dtype, buffer=shm.buf)shm_ndarray[:] = imageexisting_shm = shared_memory.SharedMemory(name=shm.name, create=False)c = np.ndarray(shape=image_shape, dtype=image_dtype, buffer=existing_shm.buf)cv2.imwrite('2.jpg', c)shm.close()existing_shm.close()existing_shm.unlink()

2. 共享内存队列

Github项目地址: https://hub.nuaa.cf/soloist-v/SharedMemoryQueue/tree/main 使用其main分支。

(不要使用Gitee上的,Gitee上的没有更新,运行有问题)

示例:使用共享内存队列传输图像
示例连接,https://download.csdn.net/download/WonderThink/88792215

from shared_memory_queue.shared_memory_record import SharedMemoryRecorder
from shared_memory_queue.kfifo_queue import Queue
import multiprocessing
import os
import cv2def producer(shm_queue: Queue):print('producer start.')for i in range(0, len(os.listdir('./img/'))):image_path = './img/' + str(i) + '.jpg'if os.path.exists(image_path):image_ndarray = cv2.imread(image_path)print(f'i: {i}, shape: {image_ndarray.shape}')shm_queue.put(item=image_ndarray, block=True, timeout=1)print('producer end.')def consumer(shm_queue: Queue, shape=None):print('consumer start.')i = 0while True:try:data = shm_queue.get(block=True, timeout=2)except:breakimage = data.reshape(shape)new_image_dir = './img2/'if not os.path.exists(new_image_dir):os.makedirs(new_image_dir)cv2.imwrite(os.path.join(new_image_dir, str(i)+'.jpg'), image)i += 1print('consumer end.')if __name__ == '__main__':image_shape = (2048, 2448, 3)   # numpy shape: 行数、列数、RGB三通道数shm_queue = Queue(buffer_size=image_shape[0] * image_shape[1] * image_shape[2] * 10)print(shm_queue.sm.get_sm_name())producer_process = multiprocessing.Process(target=producer, args=(shm_queue,))producer_process.start()consumer_process = multiprocessing.Process(target=consumer, args=(shm_queue, image_shape,))consumer_process.start()producer_process.join()consumer_process.join()shm_queue.sm.close()# SharedMemoryRecorder.release_last_sm()

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

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

相关文章

k8s-快速部署一套k8s集群

1、前置知识点 1.1 生产环境可部署Kubernetes集群的两种方式 目前生产部署Kubernetes集群主要有两种方式&#xff1a; kubeadm Kubeadm是一个K8s部署工具&#xff0c;提供kubeadm init和kubeadm join&#xff0c;用于快速部署Kubernetes集群。 二进制包 从github下载发行…

基于springboot药房管理系统源码和论文

伴随着全球信息化发展&#xff0c;行行业业都与计算机技术相衔接&#xff0c;计算机技术普遍运用于药房管理行业。实施计算机系统来管理可以降低逍遥大药房管理成本&#xff0c;使整个逍遥大药房行业的发展有显著提升。 本论文主要面向逍遥大药房管理中出现的一些常见问题&…

Advanced Science |GWAS分析揭示广东桑关键农艺性状的遗传基础

桑树是养蚕和传统医药中重要的经济植物。然而&#xff0c;桑树的遗传和进化史在很大程度上仍然是未知的。 近期&#xff0c;发表在Advanced Science&#xff08;IF17.5&#xff09;上的文章“Genomic Resequencing Unravels the Genetic Basis of Domestication, Expansion, an…

盛最多水的容器[中等]

一、题目 给定一个长度为n的整数数组height。有n条垂线&#xff0c;第i条线的两个端点是(i, 0)和(i, height[i])。找出其中的两条线&#xff0c;使得它们与x轴共同构成的容器可以容纳最多的水。返回容器可以储存的最大水量。也就是求x轴与y轴的面积。 说明&#xff1a;你不能倾…

[数据结构+算法] 给一棵树和一个sum,判断是否存在从root到叶子结点的path之和等于sum?

[数据结构算法] 给一棵树和一个sum&#xff0c;判断是否存在从root到叶子结点的path之和等于sum&#xff1f; 可以使用两种方法求解 递归 CheckTreeSumRecursive 问题转换为递归判断左右子树是否满足路径和等于sum减去当前节点的值。 迭代 CheckTreeSumNonRecursive 使用两个…

Vue2 VS Vue3 生命周期

一、生命周期的概念 Vue组件实例在创建时要经历一系列的初始化步骤&#xff0c;在此过程中Vue会在合适的时机&#xff0c;调用特定的函数&#xff0c;从而让开发者有机会在特定阶段运行自己的代码&#xff0c;这些特定的函数统称为&#xff1a;生命周期钩子&#xff08;也会叫…

【算法】BFS算法解决多源最短路问题(C++)

文章目录 前言那么什么是单源最短路 / 多源最短路呢&#xff1f;如何解决此类题&#xff1f;解法一解法二对于解法二&#xff0c;如何编写代码&#xff1f; 算法题542.01矩阵1020.飞地的数量1765.地图中的最高点1162.地图分析 前言 此前我们对 单源最短路 问题进行的讲解&…

2024年搭建幻兽帕鲁服务器价格多少?如何自建Palworld?

自建幻兽帕鲁服务器租用价格表&#xff0c;2024阿里云推出专属幻兽帕鲁Palworld游戏优惠服务器&#xff0c;配置分为4核16G和4核32G服务器&#xff0c;4核16G配置32.25元/1个月、3M带宽96.75元/1个月、8核32G配置10M带宽90.60元/1个月&#xff0c;8核32G配置3个月271.80元。ECS…

[ESP32 IDF] wifi 的应用

目录 背景知识 wifi的基本连接使用 WiFi篇—— WiFi两种模式文章中二、WiFi 的启动&#xff08;STA 及 AP 模式&#xff09; 输出现象 通过websocket控制LED 实践验证 实验现象 背景知识 WIFI是ESP32非常重要的一个功能&#xff0c;想要使用一下IDF的API实现将ESP32连…

Ubuntu中安装OpenSSL

Ubuntu中安装OpenSSL 参考&#xff1a;linux上安装Openssl步骤详解_linux安装openssl-CSDN博客 下载&#xff1a; https://www.openssl.org/source/openssl-3.0.1.tar.gz 解压&#xff1a; tar -xzvf xxxx.tar.gz 安装&#xff1a; cd openssl-3.0.12 ./config make -j3…

关于如何利用ChatGPT提高编程效率的

自从去年ChatGPT3.5推出以后&#xff0c;这一年时间在编程过程中我也在慢慢熟悉人工智能的使用&#xff0c;目前来看即使是免费的ChatGPT3.5对于编程效率的提升也是有很大帮助的&#xff0c;虽然在使用过程中确实出现了一些问题&#xff0c;本文记录下我的一些心得体会和用法。…

开发工具之GIT协同开发流程和微服务部署实践与总结

GIT协同开发流程和微服务部署的实践&#xff0c;并总结经验和教训。通过合理的GIT协同开发流程和良好的微服务部署策略&#xff0c;团队可以更高效地开发和部署软件。 ## 引言 在当今快节奏的软件开发环境中&#xff0c;采用合适的工具和流程对于实现高效协同开发和可靠部署至…

iOS 包含行间距计算富文本size

在一次开发过程中&#xff0c;发现带有行间距的富文本计算高度&#xff0c;会有不准确的情况&#xff0c;富文本内容明明很长&#xff0c;但是计算出的高度只有不到20像素&#xff0c;导致整个cell的高度计算异常。 需求上是文字固定宽度&#xff0c;最多显示3行&#xff0c;超…

FPGA高端项目:Xilinx Zynq7020系列FPGA多路视频拼接 工程解决方案 提供6套工程源码和技术支持

目录 1、前言版本更新说明给读者的一封信FPGA就业高端项目培训计划免责声明 2、相关方案推荐我已有的FPGA视频拼接叠加融合方案本方案在Xilinx Kintex7 系列FPGA上的应用本方案在Xilinx Artix7 系列FPGA上的应用 3、设计思路框架视频源选择ov5640 i2c配置及采集动态彩条多路视频…

精通Python第13篇—数据之光:Pyecharts旭日图的魔法舞台

文章目录 引言准备工作绘制基本旭日图调整颜色和样式添加交互功能定制标签和标签格式嵌套层级数据高级样式与自定义进阶主题&#xff1a;动态旭日图数据源扩展&#xff1a;外部JSON文件总结 引言 数据可视化在现代编程中扮演着重要的角色&#xff0c;而Pyecharts是Python中一个…

黑群晖使用SynologyDrive同步家庭和公司电脑文件

文章目录 前言一、黑群晖安装SynologyDrive服务二、樱花frp内网穿透2.1、创建一个隧道2.2、在群晖里面下载、安装、开启樱花frp 三、本地电脑安装SynologyDrive 前言 最近看b站学习视频&#xff0c;发现里面老师喜欢文件都是使用坚果云同步到云盘里面&#xff0c;以前我是瞧不…

OpenHarmony—仅允许在表达式中使用typeof运算符

规则&#xff1a;arkts-no-type-query 级别&#xff1a;错误 ArkTS仅支持在表达式中使用typeof运算符&#xff0c;不允许使用typeof作为类型。 TypeScript let n1 42; let s1 foo; console.log(typeof n1); // number console.log(typeof s1); // string let n2: typeof …

Nuget包缓存存放位置迁移

一、背景 默认情况下&#xff0c;NuGet会将项目中使用的包缓存到C盘&#xff0c;随着项目开发积累nuget包越来越多&#xff0c;这会逐渐挤占大量C盘空间&#xff0c;所以我们可以将nuget包缓存位置指定到其他盘中存放。 二、软件环境 win10、vs2022 三、查看当前缓存存放位…

亚信安慧AntDB打造开放创新的数据库生态

在当今信息化快速发展的时代背景下&#xff0c;亚信安慧AntDB作为一种新兴的DBMS&#xff0c;以其核心优势引起了行业内的广泛关注。它基于具有广泛全球影响力和繁荣社区支持的PostgreSQL(PG)内核&#xff0c;继承了PG的开放性与生态活力&#xff0c;同时在性能和稳定性方面进行…

【C++】引用、内联函数、auto关键字等

前言&#xff1a;在前面我们讲解了C入门基础的一些学习例如命名空间、缺省参数、函数重载等。今天我们将进一步的学习&#xff0c;跟着博主的脚步再次往前迈一步吧。 &#x1f496; 博主CSDN主页:卫卫卫的个人主页 &#x1f49e; &#x1f449; 专栏分类:高质量&#xff23;学习…