创建多处理有序字典

时间:2017-04-04 01:35:29

标签: python python-3.x dictionary multiprocessing python-multiprocessing

我想创建一个可以跨进程共享的OrderedDict实例。

我尝试了什么

简介

我已经实现了正常的dict版本,即多进程dict版本,如下所示。

import multiprocessing as mp

class BasicPen(object):
    """single process version"""

    def __init__(self, words):
        self.dogs = {"Molson": [], "Taco": [], "Lucky": []}
        self.punc = "!"
        for dog_name in self.dogs.keys():
            self.bark(dog_name, words)

    def bark(self, dog, words):
        for word in words:
            self.dogs[dog].append(word + self.punc)

class MultiPen(object):
    """multiprocess dict"""

    def __init__(self, words):
        self.man = mp.Manager()
        self.dogs = self.man.dict()
        self.dogs["Molson"] = self.man.list()
        self.dogs["Taco"] = self.man.list()
        self.dogs["Lucky"] = self.man.list()

        self.punc = "!"

        procs = [mp.Process(target=self.bark, args=(dog_name, words)) for dog_name in self.dogs.keys()]
        for pr in procs:
            pr.start()

        for pr in procs:
            pr.join()

    def bark(self, dog, words):
        for word in words:
            self.dogs[dog] += [word + self.punc]

if __name__ == '__main__':
    print("multi")
    m_pen = MultiPen(["bark", "woof", "yip"])
    print(m_pen.dogs)

    print("basic")
    b_pen = BasicPen(["bark", "woof", "yip"])
    print(b_pen.dogs)

使用multiprocessing.Namespace

我尝试使用OrderedDict使用multiprocessing.Namespace()版本来实现版本,如下所示:

import multiprocessing as mp
from collections import OrderedDict

class NamePen(object):
    """ordered dict attempt"""

    def __init__(self, words):
        man = mp.Manager()
        self.ns = man.Namespace()
        self.ns.dogs = OrderedDict()
        self.ns.dogs["Lucky"] = man.list()
        self.ns.dogs["Molson"] = man.list()
        self.ns.dogs["Taco"] = man.list()

        self.punc = "!"

        procs = [mp.Process(target=self.bark, args=(dog_name, words)) for dog_name in self.ns.dogs.keys()]
        for pr in procs:
            pr.start()

        for pr in procs:
            pr.join()

    def bark(self, dog, words):
        for word in words:
            self.ns.dogs[dog] += [word + self.punc]

if __name__ == '__main__':
    print("ordered")
    n_pen = NamePen(["bark", "woof", "yip"])
    print(n_pen.ns.dogs)

当我运行此代码时,NamePen会返回一个空的OrderedDict。我考虑的另一个选择是创建multiprocessing.Namespace并仅将属性指定为字典键,但是我找不到列出属性的方法,因为在__dict__上运行multiprocessing.Namespace并没有工作。因此,我开始怀疑multiprocessing.Namespace方法是否正确。

使用multiprocessing.managers.BaseManager

阅读完GMFBridge后,我尝试使用BaseManager推荐的方法:

import multiprocessing as mp
from multiprocessing.managers import BaseManager
from collections import OrderedDict

class MultiPen(object):
    def __init__(self, words):
        man = BaseManager()
        man.register('OrderedDict', OrderedDict)
        man.start()
        self.dogs = man.OrderedDict()
        self.dogs.update(molson=[])
        self.dogs.update(taco=[])
        self.dogs.update(lucky=[])

        self.punc = "!"

        procs = [mp.Process(target=self.bark, args=(dog_name, words)) for dog_name in self.dogs.keys()]
        for pr in procs:
            pr.start()

        for pr in procs:
            pr.join()

    def bark(self, dog, words):
        for word in words:
            self.dogs[dog] += [word + self.punc]

if __name__ == '__main__':
    print("multi")
    m_pen = MultiPen(["bark", "woof", "yip"])
    print(m_pen.dogs)

但是,我收到以下错误:

Traceback (most recent call last):
  File "multiproc_class.py", line 43, in <module>
    m_pen = MultiPen(["bark", "woof", "yip"])
  File "multiproc_class.py", line 17, in __init__
    procs = [mp.Process(target=self.bark, args=(dog_name, words)) for dog_name in self.dogs.keys()]
  File "<string>", line 2, in keys
  File "/usr/lib/python3.5/multiprocessing/managers.py", line 732, in _callmethod
    raise convert_to_error(kind, result)
multiprocessing.managers.RemoteError: 
---------------------------------------------------------------------------
Unserializable message: ('#RETURN', odict_keys(['molson', 'taco', 'lucky']))
---------------------------------------------------------------------------

我认为这意味着我正在错误地使用对象管理器。

什么是可接受的答案

我不在乎是否需要使用库或自定义类。但是,OrderedDict必须是类的属性,如上例所示。

0 个答案:

没有答案