Python:使用多维 multiprocessing.manager.list()

标签 python multidimensional-array multiprocessing

这可能不是它的预期用途,但我想知道如何使用多维 manager.list()。我可以很好地创建,像这样:

from multiprocessing import manager

test = manager.list(manager.list())

然而,每当我尝试访问测试列表的第一个元素时,它返回元素的值而不是它的代理对象

test[0]  # returns [] and not the proxy, since I think python is running __getitem__.

我有没有办法绕过这个问题并以这种方式使用 manager.list()?

最佳答案

multiprocessing documentation对此有注释:

Note

Modifications to mutable values or items in dict and list proxies will not be propagated through the manager, because the proxy has no way of knowing when its values or items are modified. To modify such an item, you can re-assign the modified object to the container proxy:

# create a list proxy and append a mutable object (a dictionary) 
lproxy = manager.list() 
lproxy.append({})
# now mutate the dictionary 
d = lproxy[0]
d['a'] = 1 
d['b'] = 2
# at this point, the changes to d are not yet synced, but by
# reassigning the dictionary, the proxy is notified of the change 
lproxy[0] = d

因此,使用多维列表的唯一方法是将您对列表的第二维所做的任何更改重新分配回顶级列表,而不是:

test[0][0] = 1

你这样做:

tmp = test[0]
tmp[0] = 1
test[0] = tmp

这不是最令人愉快的做事方式,但您可以编写一些辅助函数以使其更容易接受。

编辑:

当您将一个 ListProxy 附加到另一个 ListProxy 时,您得到一个普通列表的原因似乎是因为 pickling Proxies 的工作方式。 BaseProxy.__reduce__ 创建了一个 RebuildProxy 对象,它实际上是用来解开 Proxy 的。 RebuildProxy 看起来像这样:

def RebuildProxy(func, token, serializer, kwds):
    '''
    Function used for unpickling proxy objects.

    If possible the shared object is returned, or otherwise a proxy for it.
    '''
    server = getattr(process.current_process(), '_manager_server', None)

    if server and server.address == token.address:
        return server.id_to_obj[token.id][0]
    else:
        incref = (
            kwds.pop('incref', True) and
            not getattr(process.current_process(), '_inheriting', False)
            )
        return func(token, serializer, incref=incref, **kwds)

正如文档字符串所说,如果 unpickling 发生在管理器服务器内部,则会创建实际的共享对象,而不是它的 Proxy。这可能是一个错误,there is actually one filed已经反对这种行为。

关于Python:使用多维 multiprocessing.manager.list(),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29392650/

相关文章:

python - Airflow 任务中不允许使用 multiprocessing.Pool 吗? - 断言错误 : daemonic processes are not allowed to have children

python - Dash by Plotly vs Jupyter Dashboards 的优缺点是什么?

Matlab find 不适用于高维数组?

php - 按子键日期对多维数组进行排序?

python - 使用 Python 生成多个进程

python - 使用 TCP 同时在两个进程之间进行多处理连接

Python - setuptools - 处理两个依赖包(在一个 repo 中?)

python - Mac Swampy(Python学习模块)安装

python - 为什么 python3 lru_cache 不提供 put 和 query 方法?

在C中创建2(或3?)维字符串数组