Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/299.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 *为什么多处理序列化我的函数和闭包?_Python_Multiprocessing_Python Multiprocessing - Fatal编程技术网

Python *为什么多处理序列化我的函数和闭包?

Python *为什么多处理序列化我的函数和闭包?,python,multiprocessing,python-multiprocessing,Python,Multiprocessing,Python Multiprocessing,据 多处理分叉为*nix创建一个工作进程来执行任务。我们可以通过在fork之前的模块中设置一个全局变量来验证这一点。 如果辅助函数导入该模块并发现变量存在,则进程内存已被复制。事实如此: import os def f(x): import sys return sys._mypid # <<< value is returned by subprocess! def set_state(): import sys sys._mypid

据 多处理分叉为*nix创建一个工作进程来执行任务。我们可以通过在fork之前的模块中设置一个全局变量来验证这一点。 如果辅助函数导入该模块并发现变量存在,则进程内存已被复制。事实如此:

import os

def f(x):
    import sys
    return sys._mypid  # <<< value is returned by subprocess!


def set_state():
    import sys
    sys._mypid = os.getpid()

def g():
    from multiprocessing import Pool
    pool = Pool(4)
    try:
        for z in pool.imap(f, range(1000)):
            print(z)
    finally:
        pool.close()
        pool.join()

if __name__=='__main__':
    set_state()
    g()
我们得到:

AttributeError: Can't pickle local object 'g.<locals>.f'
Stackoverflow和internet都有很多方法可以解决这个问题。Python的标准pickle函数可以处理函数,但不能处理包含闭包数据的函数


但我们为什么要到这里来?f的一个写时拷贝版本在分叉进程的内存中。为什么它需要序列化?

Derp-必须这样,因为:

    pool = Pool(4)  <<< processes created here

    for z in pool.imap(f, range(1000)):   <<< reference to function
用法:

        def f(x):
            time.sleep(0.01)
            if x ==-1:
                raise Exception("Boo")
            return x

        for result in parallel_map(target=f,  <<< not serialized
                                   args=range(100),
                                   num_processes=8,
                                   start_method="fork"):
            pass

。。。注意:当你分叉时,程序中的每一个线程都会有一只小狗死亡。

Derp-必须这样,因为:

    pool = Pool(4)  <<< processes created here

    for z in pool.imap(f, range(1000)):   <<< reference to function
用法:

        def f(x):
            time.sleep(0.01)
            if x ==-1:
                raise Exception("Boo")
            return x

        for result in parallel_map(target=f,  <<< not serialized
                                   args=range(100),
                                   num_processes=8,
                                   start_method="fork"):
            pass

。。。有一点需要注意:当你使用叉子时,程序中的每一个线程都会导致一只小狗死亡。

没关系,我已经搞定了。这是因为在调用池和分叉进程时f不可用。您可以编写自己的答案question@user48956:请注意,这不是时间问题:构建池时存在f,但它无法知道如何隐藏对它的引用,以避免在imap期间需要传输对它的一些描述。可以想象在fork时提供了一个非全局对象的“care package”,但是因为这对spawn方法没有帮助,所以它可能不是优先级。对于spawn来说是这样的。叉子不是这样的。没关系,我想出来了。这是因为在调用池和分叉进程时f不可用。您可以编写自己的答案question@user48956:请注意,这不是时间问题:构建池时存在f,但它无法知道如何隐藏对它的引用,以避免在imap期间需要传输对它的一些描述。可以想象在fork时提供了一个非全局对象的“care package”,但是因为这对spawn方法没有帮助,所以它可能不是优先级。对于spawn来说是这样的。叉子不是这样的。