Python:使用多处理从不同进程附加到同一列表

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/42490368/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-19 21:46:26  来源:igfitidea点击:

Python:Appending to the same list from different processes using multiprocessing

pythonlistmultiprocessing

提问by Adam

I need to append objects to one list "L" from different processes using multiprocessing , but it returns empty list. How can i let many processes append to list "L"using multiprocessing ?

我需要使用 multiprocessing 将对象附加到来自不同进程的一个列表“L”,但它返回空列表。如何使用多处理让多个进程附加到列表“L”?

    #!/usr/bin/python
from multiprocessing import Process
L=[]
def dothing(i,j):
        L.append("anything")
        print i
if __name__ == "__main__":
        processes=[]
        for i in range(5):
                p=Process(target=dothing,args=(i,None))
                p.start()
                processes.append(p)
        for p in processes:
                p.join()
print L

回答by falsetru

Global variables are not shared between processes.

进程间不共享全局变量。

You need to use multiprocessing.Manager.list:

您需要使用multiprocessing.Manager.list

from multiprocessing import Process, Manager

def dothing(L, i):  # the managed list `L` passed explicitly.
    L.append("anything")

if __name__ == "__main__":
    with Manager() as manager:
        L = manager.list()  # <-- can be shared between processes.
        processes = []
        for i in range(5):
            p = Process(target=dothing, args=(L,i))  # Passing the list
            p.start()
            processes.append(p)
        for p in processes:
            p.join()
        print L

See Sharing state between processes?(Server processpart).

请参阅在进程之间共享状态?服务器进程部分)。

回答by sebtac

Using the solution provided by @falsetruworked. but still the list was not accessible beyond the "with Manager() as manager:" two changes were needed: 1.) adding "L = []" in front of the "if __name__ == "__main__":" statement

使用@falsetru工作提供的解决方案。但除了“ with Manager() as manager:”之外,列表仍然无法访问,需要进行两项更改:1.)L = []在“ if __name__ == "__main__”:”语句前添加“ ”

Must be added as for some reason the last print(L)(the "Outside of IF" one) tries to be executed as many times as there are Processes + 1 ?!?!?

必须添加,因为出于某种原因,最后一个print(L)(“IF 之外”)尝试执行与 Processes + 1 一样多的次数?!?!?

this returns an error that L is not defined and the code breaks.

这将返回 L 未定义且代码中断的错误。

2.) adding "L = list(L)" after the "p.join()" statement.

2.)L = list(L)在“ p.join()”语句后添加“ ” 。

step needed to change Manager.listto regular Python.list- otherwise calls to the manager.list return errors that object not readable.

需要更改Manager.list为常规步骤Python.list- 否则调用 manager.list 会返回对象不可读的错误。

####################
####### CODE: ######
####################

from multiprocessing import Process, Manager

def dothing(L, i):  # the managed list `L` passed explicitly.
    for j in range(5):
        text = "Process " + str(i) + ", Element " + str(j)
        L.append(text)

L = [] 

if __name__ == "__main__":
    with Manager() as manager:
        L = manager.list()  # <-- can be shared between processes.
        processes = []

        for i in range(5):
            p = Process(target=dothing, args=(L,i,))  # Passing the list
            p.start()
            processes.append(p)

        for p in processes:
            p.join()

        L = list(L) 
        print("Within WITH")
        print(L)

    print("Within IF")
    print(L)

print("Outside of IF")
print(L)

"""
#################### ###### OUTPUT: ##### ####################

"""
######################### 输出:##### ############## ######

Outside of IF
[]
Outside of IF
[]
Outside of IF
[]
Outside of IF
[]
Outside of IF
[]
Outside of IF
[]
Within WITH
['Process 2, Element 0', 'Process 2, Element 1', 'Process 2, Element 2',

'Process 2, Element 3', 'Process 2, Element 4', 'Process 1, Element 0', 'Process 1, Element 1', 'Process 1, Element 2', 'Process 1, Element 3', 'Process 1, Element 4', 'Process 0, Element 0', 'Process 0, Element 1', 'Process 0, Element 2', 'Process 0, Element 3', 'Process 0, Element 4', 'Process 4, Element 0', 'Process 4, Element 1', 'Process 4, Element 2', 'Process 4, Element 3', 'Process 4, Element 4', 'Process 3, Element 0', 'Process 3, Element 1', 'Process 3, Element 2', 'Process 3, Element 3', 'Process 3, Element 4']

'进程 2,元素 3','进程 2,元素 4','进程 1,元素 0','进程 1,元素 1','进程 1,元素 2','进程 1,元素 3','进程1, 元素 4', '进程 0, 元素 0', '进程 0, 元素 1', '进程 0, 元素 2', '进程 0, 元素 3', '进程 0, 元素 4', '进程 4,元素 0', '过程 4, 元素 1', '过程 4, 元素 2', '过程 4, 元素 3', '过程 4, 元素 4', '过程 3, 元素 0', '过程 3, 元素 1 ', '过程 3, 元素 2', '过程 3, 元素 3', '过程 3, 元素 4']

Within IF
['Process 2, Element 0', 'Process 2, Element 1', 'Process 2, Element 2', 

'Process 2, Element 3', 'Process 2, Element 4', 'Process 1, Element 0', 'Process 1, Element 1', 'Process 1, Element 2', 'Process 1, Element 3', 'Process 1, Element 4', 'Process 0, Element 0', 'Process 0, Element 1', 'Process 0, Element 2', 'Process 0, Element 3', 'Process 0, Element 4', 'Process 4, Element 0', 'Process 4, Element 1', 'Process 4, Element 2', 'Process 4, Element 3', 'Process 4, Element 4', 'Process 3, Element 0', 'Process 3, Element 1', 'Process 3, Element 2', 'Process 3, Element 3', 'Process 3, Element 4']

'进程 2,元素 3','进程 2,元素 4','进程 1,元素 0','进程 1,元素 1','进程 1,元素 2','进程 1,元素 3','进程1, 元素 4', '进程 0, 元素 0', '进程 0, 元素 1', '进程 0, 元素 2', '进程 0, 元素 3', '进程 0, 元素 4', '进程 4,元素 0', '过程 4, 元素 1', '过程 4, 元素 2', '过程 4, 元素 3', '过程 4, 元素 4', '过程 3, 元素 0', '过程 3, 元素 1 ', '过程 3, 元素 2', '过程 3, 元素 3', '过程 3, 元素 4']

Outside of IF
['Process 2, Element 0', 'Process 2, Element 1', 'Process 2, Element 2', 

'Process 2, Element 3', 'Process 2, Element 4', 'Process 1, Element 0', 'Process 1, Element 1', 'Process 1, Element 2', 'Process 1, Element 3', 'Process 1, Element 4', 'Process 0, Element 0', 'Process 0, Element 1', 'Process 0, Element 2', 'Process 0, Element 3', 'Process 0, Element 4', 'Process 4, Element 0', 'Process 4, Element 1', 'Process 4, Element 2', 'Process 4, Element 3', 'Process 4, Element 4', 'Process 3, Element 0', 'Process 3, Element 1', 'Process 3, Element 2', 'Process 3, Element 3', 'Process 3, Element 4']

'进程 2,元素 3','进程 2,元素 4','进程 1,元素 0','进程 1,元素 1','进程 1,元素 2','进程 1,元素 3','进程1, 元素 4', '进程 0, 元素 0', '进程 0, 元素 1', '进程 0, 元素 2', '进程 0, 元素 3', '进程 0, 元素 4', '进程 4,元素 0', '过程 4, 元素 1', '过程 4, 元素 2', '过程 4, 元素 3', '过程 4, 元素 4', '过程 3, 元素 0', '过程 3, 元素 1 ', '过程 3, 元素 2', '过程 3, 元素 3', '过程 3, 元素 4']

"""

回答by Ehsan Sadr

Thanks to @falsetru for suggesting the exact documentation and providing the good code. I need to keep the order for my application and by modifying the @falsetru code, now the below code preserves the order of adding items to the list.

感谢@falsetru 建议确切的文档并提供好的代码。我需要保留我的应用程序的顺序并通过修改 @falsetru 代码,现在下面的代码保留了将项目添加到列表中的顺序。

The sleep is helpful to catch the bugs otherwise it is hard to catch the problem with ordering of the list.

睡眠有助于捕捉错误,否则很难捕捉到列表排序的问题。

from multiprocessing import Process, Manager
from time import sleep

def dothing(L, i):  # the managed list `L` passed explicitly.
    L[i]= i
    sleep(4)

if __name__ == "__main__":
    with Manager() as manager:
        L = manager.list(range(50))  # <-- can be shared between processes.
        processes = []
        for i in range(50):
            p = Process(target=dothing, args=(L,i))  # Passing the list
            p.start()
            processes.append(p)
        for p in processes:
            p.join()
        print(L)