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

时间:2017-02-27 16:06:07

标签: python list 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

3 个答案:

答案 0 :(得分:14)

全局变量不在进程之间共享。

您需要使用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

请参阅Sharing state between processes¶服务器流程部分)。

答案 1 :(得分:2)

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

由于某种原因,必须添加最后一个print(L)(IF的“外部”),以使其尝试执行与进程+ 1?!?!?

一样多的次数。

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

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

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)

“”“
    ####################     ######输出:#####     ####################

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',

“过程2,元素3”,“过程2,元素4”,“过程1,元素0”, “处理1,元素1”,“处理1,元素2”,“处理1,元素3”, '处理1,元素4','处理0,元素0','处理0,元素1', 'Process 0,Element 2','Process 0,Element 3','Process 0,Element 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', 

“过程2,元素3”,“过程2,元素4”,“过程1,元素0”, “处理1,元素1”,“处理1,元素2”,“处理1,元素3”, '处理1,元素4','处理0,元素0','处理0,元素1', 'Process 0,Element 2','Process 0,Element 3','Process 0,Element 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', 

“过程2,元素3”,“过程2,元素4”,“过程1,元素0”, “处理1,元素1”,“处理1,元素2”,“处理1,元素3”, '处理1,元素4','处理0,元素0','处理0,元素1', 'Process 0,Element 2','Process 0,Element 3','Process 0,Element 4', '处理4,元素0','处理4,元素1','处理4,元素2', '处理4,元素3','处理4,元素4','处理3,元素0', “处理3,元素1”,“处理3,元素2”,“处理3,元素3”, '过程3,元素4']

"""

答案 2 :(得分:0)

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

睡眠有助于捕获错误,否则很难通过列表的排序来解决问题。

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)