SharedMemory一次性学会

388 阅读2分钟

SharedMemory是python3.8新增加的特性,主要使用内存共享,使用非常方便

使用文档链接:docs.python.org/zh-cn/3/lib…

我们可以先新建一个对象试试:

from multiprocessing import shared_memory
shm_a = shared_memory.SharedMemory(create=True, size=10)

这个方法新开辟一个空间储存内存块,我们还可以看看里面的内容:

>>> shm_a
SharedMemory('psm_d5082db5', size=10)

我们可以看到实际上是建立一个大小为10的共享内存卡,名字为psm_d5082db5

当然名字我们可以直接打印:

>>> shm_a.name
'psm_b370a3a5'

我们还可以看看究竟这个内存块里面存的什么内容,使用buf就行,里面的内容实际初始化全为0

>>> shm_a.buf
<memory at 0x7f3af310b640>
>>> list(shm_a.buf)
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0]

我们接下来,我们还可以直接新建一个一样的的内存块:

shm_b = shared_memory.SharedMemory(shm_a.name)

现在我们思考一个问题,这两个内存块是同一个内存块吗?

我们可以看看答案:

>>> shm_a is shm_b
False
>>> shm_a==shm_b
False

答案居然是不是同一个内存块,但是现在我们可以看看里面存的内容是不是一样的呢:

>>> shm_b.buf is shm_b.buf
True
>>> shm_b.buf==shm_b.buf
True

现在内容又是一样的了,这是怎么一回事呢?

我们可以看一个实验:

>>> id(shm_a)
139891162754352
>>> id(shm_b)
139891162754496

结果是shm_a和shm_b本来就是不同的东西,地址都不同

那为啥内容是一样的呢,我们可以画一张图:

image.png

 我们从图上看出,shm_a和shm_b是共用的一份数据,并不是是一个东西,因为他们三者的地址根本不是一样的,但是shm_a和shm_b使用的是一个内存块

我们再看看shm_a到底是什么类型,虽然看起来很像list,但是并不是:

>>> type( shm_a.buf)
<class 'memoryview'>

跟list类似,我们还有使用切片的方式获取数据:

>>> shm_a.buf[-1]
0
>>> shm_a.buf[-1]=2
>>> list(shm_a.buf)
[0, 0, 0, 0, 0, 0, 0, 0, 0, 2]
>>> list(shm_b.buf)
[0, 0, 0, 0, 0, 0, 0, 0, 0, 2]

至此,我们还没将共享的概念使用出来,因为我们我们最终需要在另外的进程使用这个数据,假如你在一个终端新建这些数据,但是你可以直接在另外一个终端拿到这个数据

我们可以示例一下:

我们在另外一个终端使用之前建立的内存块:

>>> existing_shm = shared_memory.SharedMemory('psm_b370a3a5')
>>> list(existing_shm.buf)
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0]

可以看到,我们可以直接拿到