函数store_in_shm
将numpy数组写入共享内存,而第二个函数read_from_shm
使用相同共享内存空间中的数据创建一个numpy数组并返回numpy数组。
但是,在Python 3.8中运行代码会产生以下分段错误:
zsh:分段错误python foo.py
为什么从函数read_from_shm
内部访问numpy数组没有问题,但是在函数外部再次访问numpy数组时出现分段错误?
输出:
From read_from_shm(): [0 1 2 3 4 5 6 7 8 9]
zsh: segmentation fault python foo.py
% /Users/athena/opt/anaconda3/envs/test/lib/python3.8/multiprocessing/resource_tracker.py:203: UserWarning: resource_tracker: There appear to be 1 leaked shared_memory objects to clean up at shutdown
warnings.warn('resource_tracker: There appear to be %d '
foo.py
import numpy as np
from multiprocessing import shared_memory
def store_in_shm(data):
shm = shared_memory.SharedMemory(name='foo', create=True, size=data.nbytes)
shmData = np.ndarray(data.shape, dtype=data.dtype, buffer=shm.buf)
shmData[:] = data[:]
shm.close()
return shm
def read_from_shm(shape, dtype):
shm = shared_memory.SharedMemory(name='foo', create=False)
shmData = np.ndarray(shape, dtype, buffer=shm.buf)
print('From read_from_shm():', shmData)
return shmData
if __name__ == '__main__':
data = np.arange(10)
shm = store_in_shm(data)
shmData = read_from_shm(data.shape, data.dtype)
print('From __main__:', shmData) # no seg fault if we comment this line
shm.unlink()
答案 0 :(得分:2)
基本上,问题似乎在于当函数返回时shm
被垃圾回收时,基础的mmap文件(由read_from_shm
中的shm
拥有)正在关闭。然后shmData
重新指向它,这是您得到段错误的地方(用于表示闭合的mmap)。这似乎是known bug,但可以通过保留对{{1 }}。
另外,所有shm
实例都希望进行SharedMemory
的处理,而其中的一个实例则在不再需要时进行close()
处理。如果您自己没有调用unlink()
,则会如前所述在GC上调用它;在Windows上,如果它是唯一当前“打开”的文件,则共享内存文件将被删除。当您在shm.close()
内调用shm.close()
时,会引入OS依赖性,因为在Windows上将删除数据,而MacOS和Linux会一直保留到调用store_in_shm
为止。
最后,尽管这没有出现在您的代码中,但是another problem当前存在于其中,从独立进程(而不是子进程)访问数据可以类似地过早删除底层mmap。 unlink
是一个非常新的库,希望所有的缺点都能很快解决。
您可以重新编写给定的示例,以保留对“第二” SharedMemory
的引用,而只需对shm
使用一个:
unlink