【问题标题】:Python dies when attempting to access shared memoryPython 在尝试访问共享内存时死机
【发布时间】:2020-09-21 04:14:24
【问题描述】:

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

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

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

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 以查看共享内存块的大小是否有限制,但我还没来跨越一切。

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

【问题讨论】:

    标签: python python-multiprocessing shared-memory python-3.8


    【解决方案1】:

    我遇到了同样的问题。对我来说,问题是 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 崩溃。

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

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

    【讨论】:

      猜你喜欢
      • 2018-05-07
      • 2019-03-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-06-12
      • 1970-01-01
      • 2017-12-09
      • 2021-04-05
      相关资源
      最近更新 更多