传递到进程中的常规列表的行为 Python

Behaviour of Regular List passed into Process Python

我只是想知道为什么作为参数传递给进程(并在进程中修改)的常规列表不会像我正常将其传递给函数一样保留为引用传递?

下面是一些示例代码:

from multiprocessing import Process

def appendThings(x):
    x.append(1)
    x.append(2)
    x.append(3)

x = []
p = Process(target=appendThings, args=(x))
p.start()
p.join()
print(x)

我希望看到:

[1,2,3]

却得到了:

[]

也欢迎对多处理有一般的了解,因为我目前正在学习 :)

多处理无法直接传递 python 对象。发送给进程的参数是一个副本。

你至少有几个选择 return 数据:

  1. 共享ctypes

  2. multiprocessing.Manager()

使用管理器的工作示例:

from multiprocessing import Process, Manager

def append_things(x):
    x.append(1)
    x.append(2)
    x.append(3)

if __name__ == '__main__':
    x = Manager().list([])
    p = Process(target=append_things, args=(x,))
    p.start()
    p.join()
    print(x)

你应该注意两件事:

  1. 您不应通过 p.terminate() 终止进程。那只会在它可以运行它的过程之前终止这个过程。

下面是一些示例代码:

from multiprocessing import Process

def appendThings(x):
        x.append(1)
        x.append(2)
        x.append(3)
        print ("I reached here!")

x = []
p = Process(target=appendThings, args=(x,))
p.start()
p.terminate()
p.join()
print(x)

只会输出以下内容:

[]

  1. 进程自己不共享内存。

因此,如果您执行以下操作:

def appendThings(x):
    x.append(1)
    x.append(2)
    x.append(3)
print (x)

它将打印:

[1,2,3]

所以在多进程中你应该使用管理器在进程之间共享对象。 Manager() 返回的管理器将支持类型 list、dict、Namespace、Lock、RLock、Semaphore、BoundedSemaphore、Condition、Event、Queue、Value 和 Array。您可以从 Python Official Doco.

阅读更多关于 Manager() 的信息

最后,您应该按如下方式修改您的代码,使其按照您的预期运行:

from multiprocessing import Process, Manager

def appendThings(x):
    x.append(1)
    x.append(2)
    x.append(3)

x = Manager().list()
#x =list()
p = Process(target=appendThings, args=(x,))
p.start()
p.join()
print(x)

所以输出将是:

[1, 2, 3]