使用python3.8中新添加的multiprocessing.shared_memory实现共享内存,但是在调用unlink的时候会报以下错误:
Traceback (most recent call last):
File "sharedmemory_client1.py", line 38, in <module>
shm.unlink()
File "/home/usr/miniconda3/lib/python3.8/multiprocessing/shared_memory.py", line 238, in unlink
_posixshmem.shm_unlink(self._name)
FileNotFoundError: [Errno 2] No such file or directory: '/psm_20602223'
使用进程A和进程B来操作这块共享内存,只有在使用multiprocessing启动其他进程的情况下,unlink()才不会报错,如果采用其他启动方式(在终端中手动启动多个,使用subprocess模块启动其他进程等),在调用unlink()时都会报错,表示找不到这块共享内存。但是任意启动方式启动的进程都可以通过name属性获取,操作和修改这块共享内存。只有unlink的时候会有问题,造成程序出错和内存泄漏。
有大佬知道如何解决或改进这个问题吗?
附测试代码:
from multiprocessing import shared_memory
import multiprocessing as mp
import subprocess
import numpy as np
import time
def another(name):
print('-------------------------')
a = np.random.randint(0, 255, (12, 12, 12), dtype=np.uint8)
shm_ = shared_memory.SharedMemory(name=name)
b = np.ndarray(a.shape, dtype=a.dtype, buffer=shm.buf)
print(b)
print('--------set new----------')
b[:] = a[:]
print(b)
shm_.close()
a = np.random.randint(0, 255, (12, 12, 12), dtype=np.uint8)
shm = shared_memory.SharedMemory(create=True, size=a.nbytes, name='fdas')
b = np.ndarray(a.shape, dtype=a.dtype, buffer=shm.buf)
b[:] = a[:]
print(shm.name)
print(b)
# 成功的
p = mp.Process(target=another, args=(shm.name, ))
p.start()
# 失败的,unlink会报错
# cmd = ['python', 'demo.py', '-n', shm.name]
# p = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
time.sleep(30)
print('--------print new-----------')
print(b)
shm.close()
shm.unlink()
p.join()
测试的demo.py
import argparse
import numpy as np
from multiprocessing import shared_memory
import time
def main(name):
print('--------start------------')
a = np.random.randint(0, 255, (12, 12, 12), dtype=np.uint8)
shm = shared_memory.SharedMemory(name=name)
b = np.ndarray(a.shape, dtype=a.dtype, buffer=shm.buf)
print(b)
print('--------set new----------')
b[:] = a[:]
print(b)
time.sleep(8)
shm.close()
if __name__ == '__main__':
parse = argparse.ArgumentParser()
parse.add_argument('-n', '--name', type=str)
args = parse.parse_args()
print(args.name)
main(args.name)