前言

multiprocessing.shared_memory 模块是 Python3.8 引入的新功能,目的是为了多进程编程提供共享内存功能,该模块主要包含两个类 SharedMemory 与 SharebleList, 后者在前者的基础之上进一步进行了封装。同时为了管理共享内存,在multiprocessing.managers定义了SharedMemoryManager, 进一步封装SharedMemory 与 SharebleList。
 

SharedMemory(name=None, create=False, size=0)

创建或者加载一个共享内存,create参数为True时,表示创建一个新的共享内存块,为False时,需要与name参数搭配使用,name参数值赋值为一个已经存在的共享内存块标识名。name参数用于标识共享内存块,为字符串,size参数指定共享内存的字节大小。

内存共享的目标是为了提高多进程通信的效率,因此在实践中,应该在每一进程中初始化一个SharedMemory实例对象,这些对象应该指向同一共享内存块。另外某些子进程可能会早于其它进程结束,因此在进程退出时,应该调用该进程内的
SharedMemory实例对象的close()方法——切断SharedMemory实例对象与共享内存块的连接。当所有进程都不在需要访问共享内存时,应该在最后一个退出进程中调用SharedMemory实例对象的unlink()方法——回收共享内存块。

如何访问或者修改共享内存的内容呢?通过SharedMemory实例对象的buf属性,该属性返回一个memoryview实例对象。buf的操作支持字节形式

import multiprocessing as mp
	from multiprocessing.shared_memory import SharedMemory, ShareableList
	
	
	def f(name):
	    shm_child = SharedMemory(name=name, create=False)
	    shm_child.buf[:10] = bytearray(list(range(10, 0, -1)))
		shm_child.close()
	    return
	
	
	if __name__ == "__main__":
	    shm_main = SharedMemory(create=True, size=10)  # size 是指字节数
	    shm_main.buf[:] = bytearray(list(range(10)))  # 只能通过字节的方式进行操作
	
	    for _ in shm_main.buf:
	        print(_, end=", ")  # 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
	    print()
	
	    p = mp.Process(target=f, args=(shm_main.name,))
	    p.start()
	    p.join()
	
	    for _ in shm_main.buf:
	        print(_, end=", ")  # 10, 9, 8, 7, 6, 5, 4, 3, 2, 1,
		
		shm_main.close()
		shm_main.unlink()

 

ShareableList(sequence=None, *, name=None)

ShareableList 实例管理的共享数据依然存储在 SharedMemory 实例中,ShareableList 实例对象的shm属性返回的就是 SharedMemory 实例。SharedMemory 访问值或者修改值,只能都过buf属性以字节形式进行操作,不大方便。而 ShareableList 实例支持存储值为“字符串、浮点型、整数型、布尔型、None”数据类型,但注意 ShareableList 实例的长度不可变更,并且不支持切片新建 ShareableList 实例对象。
在初始化时,如果 sequence 参数值不为空,则传递的实参会存储到共享内存块。如果 sequence 参数值为空,则 name 参数值必须为一个已存在的 SharedMemory.name。 最后 ShareableList 实例对象释放共享内存资源依然是通过 SharedMemory 实例对象。

def f(ls):
	    ls[1] = 99
	    ls[2] += 99
	    ls.shm.close()
	
	    return
	
	
	if __name__ == "__main__":
	    x = ShareableList([1, 2, 3])
	    print(x)  # ShareableList([1, 2, 3], name='wnsm_8ff28f7b')
	
	    p = mp.Process(target=f, args=(x,))
	    p.start()
	    p.join()
	
	    for _ in range(len(x)):
	        print(x[_], end=", ")  # 1, 99, 102
	
	    x.shm.close()
	    x.shm.unlink()

multiprocessing.managers.SharedMemoryManager

封装了 SharedMemory 与 SharebleList,使用 SharedMemoryManager 实例管理创建共享内存与释放共享内存。

import multiprocessing as mp
	from multiprocessing.managers import SharedMemoryManager
	
	
	def f(ls, s, e):
	    for idx in range(s, e):
	        ls[idx - s] = ls[e - 1 - idx]
	
	    return
	
	
	if __name__ == "__main__":
	    with SharedMemoryManager() as smm:
	        x = smm.ShareableList(list(range(10)))
	
	        p = mp.Process(target=f, args=(x, 0, len(x)))
	        p.start()
	        p.join()
	
	        for _ in x:
	            print(_, end=", ")