Python多处理:按值传递的对象?

时间:2015-01-09 20:08:51

标签: python threadpool pass-by-reference pass-by-value python-multiprocessing

我一直在尝试以下方法:

from multiprocessing import Pool

def f(some_list):
    some_list.append(4)
    print 'Child process: new list = ' + str(some_list)
    return True

if __name__ == '__main__':

    my_list = [1, 2, 3]
    pool = Pool(processes=4)
    result = pool.apply_async(f, [my_list])
    result.get()

    print 'Parent process: new list = ' + str(my_list)

我得到的是:

Child process: new list = [1, 2, 3, 4]
Parent process: new list = [1, 2, 3]

因此,这意味着 my_list 是按值传递的,因为它没有变异。 那么,当传递给另一个进程时,它是否真的按值传递的规则是什么? 感谢。

2 个答案:

答案 0 :(得分:4)

multiprocessing库使用pickle序列化对象,以便在进程之间传递它们。

这确保了安全的进程间通信,并且两个进程可以使用“相同”对象而不使用共享内存。

答案 1 :(得分:4)

正如AndréLaszlo所说,multiprocessing库需要挑选传递给multiprocessing.Pool方法的所有对象,以便将它们传递给工作进程。修剪过程导致在工作进程中创建不同的对象,因此对工作进程中的对象所做的更改不会影响父进程中的对象。在Linux上,对象有时会通过fork继承(例如multiprocessing.Process(target=func, args=(my_list,)))传递给子进程,但在这种情况下,您最终会在子进程中找到该对象的copy-on-write版本,所以当你尝试在任一过程中修改它时,你仍然会得到不同的副本。

如果您确实想要在进程之间共享对象,可以使用multiprocessing.Manager

from multiprocessing import Pool, Manager

def f(some_list):
    some_list.append(4)
    print 'Child process: new list = ' + str(some_list)
    return True

if __name__ == '__main__':

    my_list = [1, 2, 3]
    m = Manager()
    my_shared_list = m.list(my_list)
    pool = Pool(processes=4)
    result = pool.apply_async(f, [my_shared_list])
    result.get()

    print 'Parent process: new list = ' + str(my_shared_list)

输出:

Child process: new list = [1, 2, 3, 4]
Parent process: new list = [1, 2, 3, 4]