Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/symfony/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python多处理PicklingError:Can';t pickle<;类型';功能'&燃气轮机;_Python_Multiprocessing_Pickle_Python Multiprocessing - Fatal编程技术网

Python多处理PicklingError:Can';t pickle<;类型';功能'&燃气轮机;

Python多处理PicklingError:Can';t pickle<;类型';功能'&燃气轮机;,python,multiprocessing,pickle,python-multiprocessing,Python,Multiprocessing,Pickle,Python Multiprocessing,很抱歉,我不能用一个简单的例子重现这个错误,我的代码太复杂了,无法发布。如果我用ipythonshell而不是普通的Python来运行这个程序,事情就会进展顺利 我查阅了以前关于这个问题的一些笔记。它们都是由使用池调用类函数中定义的函数引起的。但我不是这样 线程thread-3中的异常: 回溯(最近一次呼叫最后一次): 文件“/usr/lib64/python2.7/threading.py”,第552行,在引导程序内部 self.run() 文件“/usr/lib64/python2.7/th

很抱歉,我不能用一个简单的例子重现这个错误,我的代码太复杂了,无法发布。如果我用ipythonshell而不是普通的Python来运行这个程序,事情就会进展顺利

我查阅了以前关于这个问题的一些笔记。它们都是由使用池调用类函数中定义的函数引起的。但我不是这样

线程thread-3中的异常: 回溯(最近一次呼叫最后一次): 文件“/usr/lib64/python2.7/threading.py”,第552行,在引导程序内部 self.run() 文件“/usr/lib64/python2.7/threading.py”,第505行,正在运行 自我目标(*自我参数,**自我参数) 文件“/usr/lib64/python2.7/multiprocessing/pool.py”,第313行,在任务处理中 放置(任务) PicklingError:无法pickle:属性查找\内置\函数失败 我将感谢任何帮助

更新:函数I pickle在模块的顶层定义。尽管它调用了一个包含嵌套函数的函数。i、 e,
f()
调用
g()
调用
h()
,它有一个嵌套函数
i()
,我正在调用
池。应用异步(f)
f()
g()
h()
都是在顶层定义的。我用这个模式尝试了一个更简单的例子,但效果很好。

下面是一个例子。特别是,如果函数是在模块的顶层定义的,那么它们才是可拾取的

这段代码:

import multiprocessing as mp

class Foo():
    @staticmethod
    def work(self):
        pass

if __name__ == '__main__':   
    pool = mp.Pool()
    foo = Foo()
    pool.apply_async(foo.work)
    pool.close()
    pool.join()
产生与您发布的错误几乎相同的错误:

Exception in thread Thread-2:
Traceback (most recent call last):
  File "/usr/lib/python2.7/threading.py", line 552, in __bootstrap_inner
    self.run()
  File "/usr/lib/python2.7/threading.py", line 505, in run
    self.__target(*self.__args, **self.__kwargs)
  File "/usr/lib/python2.7/multiprocessing/pool.py", line 315, in _handle_tasks
    put(task)
PicklingError: Can't pickle <type 'function'>: attribute lookup __builtin__.function failed

请注意,
foo
是可拾取的,因为
foo
是在顶层定义的,
foo.\uuu dict\uuuu
是可拾取的。

我发现,通过尝试在完美工作的代码段上使用探查器,我也可以准确地生成错误输出

请注意,这是在Windows上进行的(在Windows上,分叉稍微不那么优雅)

我在跑步:

python -m profile -o output.pstats <script> 
python-m profile-o output.pstats
并发现删除配置文件会删除错误,而放置配置文件会恢复错误。因为我知道以前的代码是可以工作的,所以我也快疯了。我正在检查pool.py是否有更新。。。然后有一种下沉的感觉,消除了轮廓,就是这样


在这里发布存档,以防其他人遇到。

我会使用
pathos.multiprocessing
,而不是
multiprocessing
<代码>病态。多处理是
多处理
的一个分支,它使用
dill
dill
可以序列化python中的几乎所有内容,因此您可以并行发送更多内容。
pathos
fork还可以直接处理多个参数函数,这是类方法所需要的

>>> from pathos.multiprocessing import ProcessingPool as Pool
>>> p = Pool(4)
>>> class Test(object):
...   def plus(self, x, y): 
...     return x+y
... 
>>> t = Test()
>>> p.map(t.plus, x, y)
[4, 6, 8, 10]
>>> 
>>> class Foo(object):
...   @staticmethod
...   def work(self, x):
...     return x+1
... 
>>> f = Foo()
>>> p.apipe(f.work, f, 100)
<processing.pool.ApplyResult object at 0x10504f8d0>
>>> res = _
>>> res.get()
101
>>来自pathos.multiprocessing导入ProcessingPool作为池
>>>p=池(4)
>>>类别测试(对象):
...   def plus(自身、x、y):
...     返回x+y
... 
>>>t=测试()
>>>p.map(t.plus,x,y)
[4, 6, 8, 10]
>>> 
>>>类Foo(对象):
...   @静力学方法
...   def工作(自我,x):
...     返回x+1
... 
>>>f=Foo()
>>>p.apipe(f.work,f,100)
>>>res=_
>>>res.get()
101
在这里获取
pathos
(如果您愿意,
dill
):

正如其他人所说的那样,
多处理
只能将Python对象传输到可以进行pickle处理的工作进程。如果您不能按照unutbu的描述重新组织代码,您可以使用dill的扩展酸洗/反酸洗功能来传输数据(尤其是代码数据),如下所示

此解决方案只需要安装
dill
,而不需要安装其他库,如
pathos

import os
from multiprocessing import Pool

import dill


def run_dill_encoded(payload):
    fun, args = dill.loads(payload)
    return fun(*args)


def apply_async(pool, fun, args):
    payload = dill.dumps((fun, args))
    return pool.apply_async(run_dill_encoded, (payload,))


if __name__ == "__main__":

    pool = Pool(processes=5)

    # asyn execution of lambda
    jobs = []
    for i in range(10):
        job = apply_async(pool, lambda a, b: (a, b, a * b), (i, i + 1))
        jobs.append(job)

    for job in jobs:
        print job.get()
    print

    # async execution of static method

    class O(object):

        @staticmethod
        def calc():
            return os.getpid()

    jobs = []
    for i in range(10):
        job = apply_async(pool, O.calc, ())
        jobs.append(job)

    for job in jobs:
        print job.get()
这个解决方案只需要安装dill,而不需要安装其他库

def apply_packeted_function_for_map((转储的_function、item、args、kwargs)):
"""
将转储函数解包为目标函数,并使用参数调用它。
:param(函数、项、参数、kwargs):
转储函数及其参数的元组
:返回:
目标函数的结果
"""
目标函数=卸载(卸载函数)
res=目标函数(项目,*args,**kwargs)
返回res
def打包功能用于打包映射(目标打包功能、项目、*args、**kwargs):
"""
将函数和参数打包到可以从一个
多处理。处理到另一个。主要问题是:
«多处理.Pool.map*»或«应用*»
不能使用类方法或闭包。
它用«dill»解决了这个问题。
它使用目标函数作为参数,转储它(«with dill»)
并返回带有目标函数参数的转储函数。
为了获得更高的性能,我们只转储目标函数本身
不要放弃它的论点。
如何使用(伪代码):
~>>>导入多处理
~>>>图像=[…]
~>>>pool=multiprocessing.pool(100500)
~>>>features=pool.map(
~…*打包功能\u用于\u映射(
~…超级(提取器,自身)。提取功能,
~…图像,
~…type='png'
~.**选择,
~...     )
~... )
~>>>
:参数目标函数:
函数,您希望像target_函数一样执行它(item,*args,**kwargs)。
:参数项:
地图项目列表
:param args:
目标函数的位置参数(项、*args、**kwargs)
:param kwargs:
目标函数的命名参数(项,*args,**kwargs)
:return:tuple(函数包装、转储项)
它返回一个元组
*函数包装器,解包并调用目标函数;
*压缩目标函数及其参数的列表。
"""
转储函数=转储(目标函数)
dumped_items=[(dumped_函数、item、args、,
import os
from multiprocessing import Pool

import dill


def run_dill_encoded(payload):
    fun, args = dill.loads(payload)
    return fun(*args)


def apply_async(pool, fun, args):
    payload = dill.dumps((fun, args))
    return pool.apply_async(run_dill_encoded, (payload,))


if __name__ == "__main__":

    pool = Pool(processes=5)

    # asyn execution of lambda
    jobs = []
    for i in range(10):
        job = apply_async(pool, lambda a, b: (a, b, a * b), (i, i + 1))
        jobs.append(job)

    for job in jobs:
        print job.get()
    print

    # async execution of static method

    class O(object):

        @staticmethod
        def calc():
            return os.getpid()

    jobs = []
    for i in range(10):
        job = apply_async(pool, O.calc, ())
        jobs.append(job)

    for job in jobs:
        print job.get()
Can't pickle <type 'function'>: attribute lookup __builtin__.function failed
import dill
import itertools
def run_dill_encoded(payload):
    fun, args = dill.loads(payload)
    res = fun(*args)
    res = dill.dumps(res)
    return res

def dill_map_async(pool, fun, args_list,
                   as_tuple=True,
                   **kw):
    if as_tuple:
        args_list = ((x,) for x in args_list)

    it = itertools.izip(
        itertools.cycle([fun]),
        args_list)
    it = itertools.imap(dill.dumps, it)
    return pool.map_async(run_dill_encoded, it, **kw)

if __name__ == '__main__':
    import multiprocessing as mp
    import sys,os
    p = mp.Pool(4)
    res = dill_map_async(p, lambda x:[sys.stdout.write('%s\n'%os.getpid()),x][-1],
                  [lambda x:x+1]*10,)
    res = res.get(timeout=100)
    res = map(dill.loads,res)
    print(res)
from multiprocessing.pool import ThreadPool as Pool