使用Python共享内存的分段错误

时间:2020-09-02 20:40:21

标签: python macos numpy shared-memory python-3.8

函数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()

1 个答案:

答案 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