Python 多处理:按值传递对象?
Python multiprocessing: object passed by value?
我一直在尝试以下方法:
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 是按值传递的,因为它没有变异。
那么,传给另一个进程的时候真的是按值传递的规则吗?
谢谢
multiprocessing
library serializes objects using pickle
在进程之间传递它们。
这确保了安全的进程间通信,并且两个进程可以在不使用共享内存的情况下使用 "same" 对象。
正如 André Laszlo 所说,multiprocessing
库需要 pickle 传递给 multiprocessing.Pool
方法的所有对象,以便将它们传递给工作进程。酸洗过程导致在工作进程中创建一个不同的对象,因此对工作进程中的对象所做的更改不会影响父进程中的对象。在 Linux 上,对象有时会通过 fork
继承(例如 multiprocessing.Process(target=func, args=(my_list,))
)传递给子进程,但在这种情况下,您最终会得到对象的写时复制版本子进程,因此当您尝试在任一进程中修改它时,您仍然会得到不同的副本。
如果你想在进程之间共享一个对象,你可以使用 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]
我一直在尝试以下方法:
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 是按值传递的,因为它没有变异。 那么,传给另一个进程的时候真的是按值传递的规则吗? 谢谢
multiprocessing
library serializes objects using pickle
在进程之间传递它们。
这确保了安全的进程间通信,并且两个进程可以在不使用共享内存的情况下使用 "same" 对象。
正如 André Laszlo 所说,multiprocessing
库需要 pickle 传递给 multiprocessing.Pool
方法的所有对象,以便将它们传递给工作进程。酸洗过程导致在工作进程中创建一个不同的对象,因此对工作进程中的对象所做的更改不会影响父进程中的对象。在 Linux 上,对象有时会通过 fork
继承(例如 multiprocessing.Process(target=func, args=(my_list,))
)传递给子进程,但在这种情况下,您最终会得到对象的写时复制版本子进程,因此当您尝试在任一进程中修改它时,您仍然会得到不同的副本。
如果你想在进程之间共享一个对象,你可以使用 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]