首页 > 解决方案 > Python 在尝试访问共享内存时死机

问题描述

我正在编写一段代码,该代码将一些共享内存块(使用 Python3.8 中的 SharedMemory.shared_memory 创建)作为输入,其中包含一个有序的数字列表以及一个 numpy 数组,目标是一些最终的共享内存中的数组,它是这两个集合的有序联合。

共享内存块非常大(大约 8 Gb 到它失败的点),所以为了加快联合,共享内存的输入块在一些进程之间平均分配,然后在它们的小块上单独执行联合,结果被合并到另一个(单独的)共享内存块中。这些联合执行多次,因此实际上在程序的生命周期中分配了许多大小增加的共享内存块,但是一旦联合完成,旧的共享内存块就被取消链接(因此在任何给定的时间,最多有两个活动的共享内存块,每个块在死亡点的大小约为 8Gb)。

我遇到的问题是,在调用访问共享内存块时,进程会终止而不会引发任何错误。这项工作是在一个子进程(我将其称为工作者)中完成的,它是从另一个从主进程创建的子进程中产生的。工作进程似乎没有引发任何错误,我尝试使用其他方法来捕获任何错误,例如try:... except Exception as e:...在工作进程中使用 a ,然后通过管道将错误信息传回主进程,但就我而言可以说没有错误被提出,工人似乎默默地死去。具体来说,它在工作进程的以下行中死亡:

shm_block = mp.shared_memory.SharedMemory(name=shm_key)

我一直在具有 64Gb RAM 的 Linux 服务器上运行代码,并且调用df –k /dev/shm表明我在共享内存中有 32Gb。我一直在使用 8 个工作进程运行该程序(但它也因更少的进程而失败,比如 2 个和 4 个工作进程),并且它似乎可以平稳地运行到刚好高于 8Gb 的这个阈值,此时工作人员会默默地死掉。我试图在更小的机器(10Gb RAM)上使用相同的数据集创建一个最小的可重现示例,但在这种情况下会引发 MemoryError。我尝试查看位于 SharedMemory 模块下方的shm_openmmap以查看共享内存块的大小是否有限制,但我没有遇到任何问题。

任何建议将不胜感激,如果有帮助,我们很乐意提供更多代码。提前致谢!

标签: pythonpython-multiprocessingshared-memorypython-3.8

解决方案


我遇到了同样的问题。对我来说,问题是 Python 不会抛出的访问冲突。

from multiprocessing import shared_memory
shm_list = shared_memory.ShareableList([0] * 29, name='shm_xyz')
b = 10 ** 1000
try:
    shm_list[4] = b
except Exception as e:
    print(e)
print('I arrived at that point')

通常,这应该会引发参数超出范围错误。在我的项目中,我所做的几乎相同,但由于某种原因(我无法重现),它不会抛出异常,而是简单地崩溃。当我从 c++ 调用 python 脚本时,我注意到,一个 AccessViolation 被抛出。据我了解,此 AccessViolation 是由 Windows 或硬件级别引发的,因此立即使 python 崩溃。

我的解决方案是避免使用太大的数字。

对不起,如果我没有太多帮助,我想我仍然会分享它,以防有人在像我一样搜索问题时发现这个问题。


推荐阅读