创建和更新 multiprocessing.Manager 对象内的嵌套字典和列表

2024-02-11

我在里面创建了一个嵌套字典multiprocessing.Manager.dict目的。字典方法如update, clear等,当我将它们应用到嵌套字典时不起作用。这是一个例子:

from multiprocessing import Manager, Process


def worker(shared_object):
    print(f'Before defining the nested dictionary: {shared_object}')
    shared_object['nested'] = {
        'first_key': 'first_value'
    }
    print(f'After defining the nested dictionary: {shared_object}')
    shared_object['nested'].update(
        {
            'second_key': 'second_value'
        }
    )
    print(f'After updating the nested dictionary: {shared_object}')


if __name__ == '__main__':
    with Manager() as manager:
        shared_dict = manager.dict()
        worker_one = Process(target=worker, args=(shared_dict,))
        worker_one.start()
        worker_one.join()

这是结果:

Before defining the nested dictionary: {}
After defining the nested dictionary: {'nested': {'first_key': 'first_value'}}
After updating the nested dictionary: {'nested': {'first_key': 'first_value'}}

我能做些什么?


您对共享字典的用法与以下内容相同,并且可以重写为:

temp = shared_object['nested']
temp.update({'second_key': 'second_value'})

当您请求的值时nestedkey来自共享字典,它存储在当前进程的内存空间中。这意味着您对此字典所做的任何更改都不会反映在管理器内存储的共享字典中,因为管理器在检索字典的子集后无法知道您对字典做了什么。因此,您需要做的就是通知经理您对嵌套字典进行了更改。您可以通过两种方式执行此操作:

使用更新后的值显式调用管理器对象

这可能是这里最简单(就性能而言也是最快)的修复,在对嵌套字典进行任何更改后,显式将键的值设置为更改后的字典:

temp = shared_object['nested']
temp.update({'second_key': 'second_value'})
shared_object['nested'] = temp

这样做可以让管理者知道被管理的对象发生了变化。

为嵌套字典创建另一个托管对象(手动与自动)

实现此目的的另一种方法是为嵌套字典创建托管对象并存储它。但是,请记住,如果对象的嵌套级别非常深,这很快就会变得不方便。这是因为对于每个嵌套字典,您需要创建另一个托管对象。此外,如果您创建的子进程是守护进程(使用时默认为multiprocessing.Pool)并且他们需要在共享字典中添加自己的嵌套对象。这是因为要创建托管对象,您需要启动管理器进程,而守护进程无法生成自己的进程。

但是,如果您让共享字典足够负责,在有人尝试在其中存储嵌套字典时自动创建托管对象,那么这两个问题都可以很快得到解决。这消除了手动执行此操作的负担,下面给出了如何实现这一点的示例(它适用于列表和字典):

from multiprocessing.managers import SyncManager, MakeProxyType, ListProxy, State
from multiprocessing import Process, Lock
from collections import UserDict
from collections import UserList


class ManagerList(UserList):

    def __check_state(self):
        global manager
        global lock

        # Managers are not thread-safe, protect starting one from within another with a lock
        with lock:
            if manager._state.value != State.STARTED:
                manager.start(initializer=init)

    def __setitem__(self, key, value):
        global manager
        self.__check_state()

        if isinstance(value, list):
            value = manager.list(value)
        elif isinstance(value, dict):
            value = manager.dict(value)
        return super().__setitem__(key, value)


class ManagerDict(UserDict):

    def __check_state(self):
        global manager
        global lock

        # Managers are not thread-safe, protect starting one from within another with a lock
        with lock:
            if manager._state.value != State.STARTED:
                manager.start(initializer=init)

    def __setitem__(self, key, value):
        global manager
        self.__check_state()

        if isinstance(value, list):
            value = manager.list(value)
        elif isinstance(value, dict):
            value = manager.dict(value)
        return super().__setitem__(key, value)


ManagerDictProxy = MakeProxyType('DictProxy', (
    '__contains__', '__delitem__', '__getitem__', '__iter__', '__len__',
    '__setitem__', 'clear', 'copy', 'get', 'items',
    'keys', 'pop', 'popitem', 'setdefault', 'update', 'values'
    ))
ManagerDictProxy._method_to_typeid_ = {
    '__iter__': 'Iterator',
    }

SyncManager.register('list', ManagerList, ListProxy)
SyncManager.register('dict', ManagerDict, ManagerDictProxy)


def init():
    global manager
    global lock

    lock = Lock()
    manager = SyncManager()

def worker(shared_object):
    print(f'Before defining the nested dictionary: {shared_object}')
    shared_object['nested'] = {
        'first_key': 'first_value',
    }
    print(f'After defining the nested dictionary: {shared_object["nested"]}')
    shared_object['nested'].update(
        {
            'second_key': 'second_value'
        }
    )
    print(f'After updating the nested dictionary: {shared_object["nested"]}')


if __name__ == "__main__":
    manager = SyncManager()
    manager.start(initializer=init)

    d = manager.dict()  # It works with manager.list() too
    p = Process(target=worker, args=(d, ))
    p.start()
    p.join()

这使用了__setitem__dunder 方法检查分配给字典的值是否是另一个列表或字典,如果是,它会为它们创建一个托管对象并存储它。现在对这些嵌套字典/列表所做的任何更改也将反映在原始字典中。这适用于任意数量的嵌套级别。

但是,请记住,只有当数据类型为list or dict(或其子类)。此外,它还为每个嵌套级别创建一个管理器进程。因此,使用第一种方法总是比使用这种方法更快,尽管这种方法更方便。

Output

Before defining the nested dictionary: {}
After defining the nested dictionary: {'first_key': 'first_value'}
After updating the nested dictionary: {'first_key': 'first_value', 'second_key': 'second_value'}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

创建和更新 multiprocessing.Manager 对象内的嵌套字典和列表 的相关文章

随机推荐

  • Spring MVC 与 hibernate Validator 来验证单个基本类型

    下面是我遇到问题的映射方法 无论我传递给它什么值 验证都会返回 通过验证 RequestMapping value test method RequestMethod POST ResponseBody public String getT
  • 网站不同部分使用不同的 SSL 证书

    我在 example com 上有一个网站 它从 s example com 亚马逊 Cloudfront 发行版 加载所有静态组件 现在我想让 example com 的一些页面使用 https 所以我想我应该为 example com
  • 了解 Kafka 主题和分区

    我开始学习卡夫卡 在阅读过程中 我想到了一些问题 当生产者生成消息时 它会指定topic它想要将消息发送到 是对的吗 它关心分区吗 当订阅者运行时 它是否指定其组ID 以便它可以成为同一主题或该组消费者感兴趣的多个主题的消费者集群的一部分
  • 使用 Jquery 将剪贴板图像复制到网页中

    我想将剪贴板图像复制到网页中 前任 用户单击打印屏幕按钮 打开网页 单击 CTRL V 图像将上传到网页 可以使用 jquery javascript 或 PHP 吗 在火狐浏览器中可以吗 提前致谢 恐怕不是 不是 您必须让用户将屏幕截图保
  • 在哪里更改oracle 11g中的NLS_DATE_FORMAT?

    我需要更改存储过程中的 NLS DATE FORMAT 似乎它是一个会话变量 我应该在哪里更改变量掩码 应该在全局声明中还是其他地方完成 我的意思是从前端 如果您想更改过程中的 NLS 参数 则可以使用DBMS SESSION SET NL
  • 元素“标题”出现次数太少,ASP.NET.MVC 母版页中出现 XHTML 验证警告

    我在 ASP NET MVC 母版页中收到以下 XHTML 验证警告 验证 XHTML 1 0 Transitional 元素 title 出现的次数太少 母版页的标题标签包含在 head 标签的 ContentPlaceHolder 中
  • NLTK数据安装问题

    我正在尝试在 Mac OSX 10 9 上安装 NLTK Data NLTK 3 0文档中提到 要设置的下载目录是 usr share nltk data 用于集中安装 但对于这条路径 我收到错误 OSError Errno 13 权限被拒
  • 运算符重载Python自定义类

    假设我想重载一个运算符 假设 现在 对于我创建的一些课程 class A object code here 进而 a A b A 我会做什么来定义 c a b 或类似的规定 注意 这个问题纯粹是理论上的 我可能会在某个时候使用它 只是目前不
  • C++:这个运算符^是什么? [复制]

    这个问题在这里已经有答案了 int main std string original Hello world std string decrypted std string encrypted char key x cout lt lt O
  • 使用 SqlConnection 和 VB.NET 创建 ASP.NET 聚合源

    这似乎是 Scott Mitchell 撰写的一篇很棒的文章 用于创建联合提要ASP NET 3 5 对我来说 问题是它使用 C 和 Linq 目前我对这两种语言不太熟悉 http dotnetslackers com articles a
  • Elastic Beanstalk 无法识别文件的绝对路径,返回 FileNotFoundError

    我正在使用 AWS Elastic Beanstalk 运行 Flask 应用程序 应用程序部署成功 但我的代码中有一个任务使用 pandasread csv从 csv 文件中提取数据 代码行是 form1 pd read csv opt
  • 为什么 numberOfSectionsInTableView 在 UITableViewController 中被调用两次?

    是否还有其他原因 除了调用 reloadData 为什么 numberOfSectionsInTableView 被调用两次 我进行了调试 发现在初始启动期间 当没有调用自定义 reloadData 语句时 它会被调用两次 我已经使用 IB
  • 部署 MVC,无需关闭整个站点

    假设我想对我的 MVC 项目的一个视图中的某些内容进行更改 一些非常简单的事情 比如删除一个句子或添加一个句号或其他东西 因此 据我所知 我必须重新发布整个网站 然后删除整个网站并用新发布的集合替换它 我想知道是否有一种方法 如果我对单个页
  • 如何从 Ubuntu 19.10 卸载 python 3.7?

    我在用着Ubuntu 19 10 其中有python的版本3 7 发布后python 3 8 我已经安装了 现在我想卸载python 3 7这样每当我打电话时python3在我的终端中 它总是会调用python3 8 您不需要为此卸载旧版本
  • 如何在不绑定V​​iewModel(MVVM)中UI的情况下使用android导航?

    我正在使用在 Google I O 2018 上展示的 Android 导航 似乎我可以通过绑定到某些视图或使用NavHost从 Fragment 中获取它 但我需要的是根据几个条件从我的第一个片段导航到 ViewModel 的另一个特定视
  • if else 和 #if #else #endif 之间的区别

    我很困惑if else and if else endif结构体 它们之间有什么区别 我应该在哪些具体情况下使用它们 if and else 条件在运行时评估 if else由预处理器在编译之前进行评估
  • 为什么“a”标签需要“tabindex=0”?

    我正在开发一个网络应用程序 其中一个重复的应用程序a当我通过 Tab 键浏览页面时 锚点 元素没有获得键盘焦点 仅当我添加tabindex 0我可以点击它吗 虽然我的目标是使焦点可见 但我正在使用 jQuery 片段确定元素是否获得焦点 W
  • 是否有一种简洁的方法在 Google Guava 中为 InputStream 创建 InputSupplier?

    Google Guava 中有一些工厂方法来创建 InputSuppliers 例如从一个byte ByteStreams newInputStreamSupplier bytes 或者从一个File Files newInputStrea
  • 为什么在 Alpine Linux 上安装 Pandas 需要很长时间

    我注意到 使用基本操作系统 Alpine 与 CentOS 或 Debian 在 Docker 容器中安装 Pandas 和 Numpy 它的依赖项 需要更长的时间 我在下面创建了一个小测试来演示时差 除了 Alpine 需要几秒钟更新和下
  • 创建和更新 multiprocessing.Manager 对象内的嵌套字典和列表

    我在里面创建了一个嵌套字典multiprocessing Manager dict目的 字典方法如update clear等 当我将它们应用到嵌套字典时不起作用 这是一个例子 from multiprocessing import Mana