python shared_memory 共享内存
-
背景
python利用多核就需要开启多进程,如果多进程之间需要共享数据又不希望引入第三方的服务,就需要使用共享内存。 -
multiprocessing.shared_memory
python 3.8之后,python内置的multiprocessing库提供了一种新的共享内存方式,shared_memory。
这种方式是直接让系统划出一块内存供多进程访问,进程访问这块内存时,无需经过代理等等过程,所以性能较高。 -
简单使用
import random
import time
from multiprocessing import Lock, Process
from multiprocessing.shared_memory import SharedMemory
def worker_on_sharememory(shared_mem: SharedMemory, lock):
"""
操作共享内存
"""
time.sleep(random.randint(1, 5))
with lock:
s = str(random.randint(0, 9))
shared_mem.buf[12:13] = s.encode()
print(shared_mem.buf[:13].tobytes().decode("utf-8"))
# 关闭子进程对共享内存的访问
shared_mem.close()
if __name__ == "__main__":
# 系统一般会按内存页大小分配内存,通常都是4kb,比如,申请1字节内存,系统实际会分配4kb,但是可以安全使用的还是1字节,剩余的是浪费的。
# 实际使用中,一般不需要考虑这个问题,size指定多少就最多用多少,不要溢出。
shared_mem = SharedMemory(
create=True,
size=4096,
name="test_memory",
) # 申请4096字节内存
# 使用共享内存
shared_mem.buf[:12] = b"Hello World!"
lock = Lock()
process_list = []
for i in range(5):
p = Process(target=worker_on_sharememory, args=(shared_mem, lock))
p.start()
process_list.append(p)
for p in process_list:
p.join()
# 关闭父进程对共享内存的访问
shared_mem.close()
# 标记共享内存区域为可删除,这是父进程必须要做的事情,否则共享内存可能不会被系统回收。
shared_mem.unlink()
-
注意事项
1.共享内存的大小在创建时指定,且不能动态调整。
# 创建 100 字节的共享内存
shared_mem = SharedMemory(create=True, size=100)
2.共享内存是无锁的,多进程数据同步问题需要自行加锁处理
3.共享内存可以命名,在整个计算机中,命名必须唯一。通过name命名,以便多个进程访问同一块内存区域。
# 创建命名共享内存
shared_mem = SharedMemory(create=True, size=100, name='test_memory')
# windows平台上,共享内存的名称不能包含反斜杠'\'
# 在其他进程中访问同一块共享内存
shared_mem = SharedMemory(name='test_memory')
4.共享内存不会自动回收,必须显式调用close()和unlink()释放资源.
**close()**:关闭当前进程对共享内存的访问。
**unlink()**:标记共享内存区域为可删除,当所有进程都关闭访问后,系统会自动回收该内存区域。
基本流程: 子进程访问完后关闭访问,父进程等子进程们结束后,关闭访问并标记可删除,系统自动回收。
5.查看和删除共享内存
linux中,通过ipcs -m和ipcrm -m <shm_id>来查看和删除共享内存。
# windows系统会自动清理未释放的共享内存,但还是建议手动unlink清理。
6.跟踪器警告
"""
UserWarning: resource_tracker: There appear to be 1 leaked shared_memory objects to clean up at shutdown
"""
未正确释放共享内存的程序,在程序执行之后,会发出以上警告内容。 -
特点
1.shared_memory的性能非常高,因为进程可以直接操作内存区域,避免了数据复制和进程间通信的开销。
2.无锁,数据同步问题需要自行加锁,加锁也会影响性能。
浙公网安备 33010602011771号