当我们尝试使用SharedMemoryManager(Python 3.8)替换BaseManager时,为什么会出现NameError错误?

5

Python 3.8引入了新的共享内存特性。我们尝试使用SharedMemoryManager,但出现了NameError错误。

我认为可能是在我们复杂的场景中做错了什么,因此我使用Python文档片段对其进行了分解。

try:
    # python >= 3.8
    from multiprocessing.managers import SharedMemoryManager as Manager
except:
    # python < 3.8
    from multiprocessing.managers import BaseManager as Manager

class MathsClass:
    def add(self, x, y):
        return x + y
    def mul(self, x, y):
        return x * y

class MyManager(Manager):
    pass

MyManager.register('Maths', MathsClass)

if __name__ == '__main__':
    with MyManager() as manager:
        maths = manager.Maths()
        print(maths.add(4, 3))         # prints 7
        print(maths.mul(7, 8))         # prints 56


这基本上是从多进程文档中提取的(除了回退导入),在Python 3.7中工作正常,但在Python 3.8中会产生以下错误:
Traceback (most recent call last):
  File "scripts/debug_shared_memory_issue.py", line 21, in <module>
    maths = manager.Maths()
  File "/usr/lib/python3.8/multiprocessing/managers.py", line 740, in temp
    token, exp = self._create(typeid, *args, **kwds)
  File "/usr/lib/python3.8/multiprocessing/managers.py", line 625, in _create
    id, exposed = dispatch(conn, None, 'create', (typeid,)+args, kwds)
  File "/usr/lib/python3.8/multiprocessing/managers.py", line 91, in dispatch
    raise convert_to_error(kind, result)
multiprocessing.managers.RemoteError: 
---------------------------------------------------------------------------
Traceback (most recent call last):
  File "/usr/lib/python3.8/multiprocessing/managers.py", line 210, in handle_request
    result = func(c, *args, **kwds)
  File "/usr/lib/python3.8/multiprocessing/managers.py", line 1312, in create
    if hasattr(self.registry[typeid][-1], "_shared_memory_proxy"):
NameError: name 'self' is not defined
---------------------------------------------------------------------------

Python 3.8的发布说明和文档中提到SharedMemoryManager是"BaseManager的子类",因此我们期望它可以作为一种即插即用的替代方案。但事实并非如此。在查看当前的CPython 3.8分支时,似乎没有相关的更改。然而,在Python 3.9中,create函数有一个显式的self参数。但是3.9还在进行中,因此我们不想在生产软件中使用它。
谢谢您的帮助!
1个回答

1

这是一个在python/cpython@142566c(v3.9.0a1)中修复的错误。

您可以从python/cpython/blob/v3.9.0a1/Lib/multiprocessing/managers.py#L1269-L1277打补丁:

from multiprocessing.managers import SharedMemoryManager as Manager

import sys

if sys.version_info < (3, 9):
    from multiprocessing.managers import Server, SharedMemoryServer

    def create(self, c, typeid, /, *args, **kwargs):
        if hasattr(self.registry[typeid][-1], "_shared_memory_proxy"):
            kwargs['shared_memory_context'] = self.shared_memory_context
        return Server.create(self, c, typeid, *args, **kwargs)

    SharedMemoryServer.create = create

谢谢!我今天会尝试这个方法,如果有效的话就接受这个答案。不知道是否有计划在3.8中修复这个问题? - Frederik Petersen

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接