it-swarm.com.de

Python: Anhängen an dieselbe Liste aus verschiedenen Prozessen mit Multiprocessing

Ich muss mit Multiprocessing Objekte aus verschiedenen Prozessen an eine Liste "L" anhängen, aber es wird eine leere Liste zurückgegeben. Wie kann ich viele Prozesse mit Multiprocessing an die Liste "L" anhängen lassen?

    #!/usr/bin/python
from multiprocessing import Process
L=[]
def dothing(i,j):
        L.append("anything")
        print i
if __== "__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
6
Adam

Globale Variablen werden nicht von Prozessen gemeinsam genutzt.

Sie müssen multiprocessing.Manager.list verwenden:

from multiprocessing import Process, Manager

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

if __== "__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

Siehe Freigabezustand zwischen Prozessen ( Serverprozess part).

13
falsetru

Die von @falsetru bereitgestellte Lösung hat funktioniert. Über die "with Manager() as manager:" konnte jedoch nicht auf die Liste zugegriffen werden. Es waren zwei Änderungen erforderlich: 1.) Hinzufügen von "L = []" vor der "if __== "__main__": "- Anweisung

Muss hinzugefügt werden, da die letzte print(L) (die "Outside of IF") so oft ausgeführt werden soll, wie Processes + 1?!?!?

dies gibt einen Fehler zurück, bei dem L nicht definiert ist und der Code bricht.

2.) Hinzufügen von "L = list(L)" nach der "p.join()" -Anweisung.

schritt erforderlich, um Manager.list in regulär Python.list zu ändern - andernfalls geben Aufrufe der manager.list Fehler zurück, deren Objekt nicht lesbar ist.

####################
####### 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 __== "__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)

"" "
#################### ###### AUSGABE: ##### ## ##################

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

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

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

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

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

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

"""
1
sebtac

Danke an @falsetru für den Vorschlag der genauen Dokumentation und die Bereitstellung des guten Codes. Ich muss die Reihenfolge für meine Anwendung beibehalten und durch Ändern des @ falsetru-Codes die Reihenfolge des Hinzufügens von Elementen zur Liste beibehalten. 

Der Schlaf ist hilfreich, um die Fehler abzufangen, ansonsten ist es schwierig, das Problem bei der Bestellung der Liste zu erkennen.

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 __== "__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)
0
Ehsan Sadr