可以multiprocessing.Manager()。Queue()处理复杂对象吗?

时间:2015-06-24 06:48:42

标签: python multiprocessing

def load_cache(cache_name, resultq=None):

    with open(cache_name, 'rb') as input:
        cached_data = pickle.load(input)

    if not resultq:
        return cached_data
    else:
        try:
            resultq.put( (cache_name, cached_data) )    # getting error here
        except:
            print sys.exc_info()[1]

q = multiprocessing.Manager().Queue()
info = ['a', 'b', 'c', 'd']
procs = []
for i in zip(info, itertools.repeat(q)):
    p = multiprocessing.Process(target=load_cache, args=i)
    procs.append(p)
    p.daemon = False
    p.start()

for p in procs:
    p.join()

输出:

Traceback (most recent call last):
    File "/usr/lib/python2.7/multiprocessing/managers.py", line 240, in serve_client
         request = recv()
TypeError: __new__() takes at least 2 arguments (1 given)

不确定此错误的含义或如何解决此问题。有什么想法吗?

注意:
如果我将cached_data设为cached_data={}之类的虚拟值,则可以正常工作 cached_data是一个包含复杂Python对象的词典

如果我移除try/except周围的resultq.put()

File "main.py" line 20 in load_cache
    resultq.put((cache_name, cached_data))
File "<string>", line 2, in put
File "/usr/lib/python2.7/multiprocessing/managers.py", line 774, in _callmethod
    raise convert_to_error(kind, result)
RemoteError:

3 个答案:

答案 0 :(得分:1)

从你的问题中可以很难说出发生了什么,因为有这条线

q = multiprocessing.Manager().Queue()

引用Queue,但它是唯一的一个。目前还不清楚您的错误源自何处,因为导致错误的行似乎不在您的列表中。

multiprocessing.Queue从一个地方到另一个地方挖掘字节。字节数很少或很多,但它们并不简单或复杂。为了通过Queue移动对象,需要对它们进行序列化/反序列化(转换为/从字节形式)。 已知pickle(和cPickle)在可序列化方面存在问题。 dill你可能会有更好的运气(我对此有过积极的体验)。来自dill文档:

  

Dill扩展了python的'pickle'模块,用于将python对象序列化和反序列化为大多数内置python类型。 ... Dill为用户提供与'pickle'模块相同的界面,还包括一些附加功能。除了pickling python对象之外,dill还提供了在单个命令中保存解释器会话状态的功能...... Dill可用于将python对象存储到文件中,但主要用途是通过网络发送python对象作为字节流。

答案 1 :(得分:0)

resultq.put((cache_name, pickle.dumps(cached_data))) 

工作

答案 2 :(得分:0)

它不能。作为文档says

  

Manager()返回的经理将支持listdictNamespaceLockRLockSemaphore类型,BoundedSemaphoreConditionEventQueueValueArray