Also, ich versuche, eine Anwendung zu schreiben, die Django als ORM verwendet, da es beide hinter den Kulissen Verarbeitung und ein einfach zu bedienendes Front-End tun müssen. Seine Kernfunktionalität ist die Verarbeitung von Daten, die sich in der Datenbank befinden, in einem Prozess mit hoher CPU (im Grunde Monte-Carlo-Simulationen), und ich möchte Multiprozessing implementieren, speziell mit Pool (ich bekomme 4 Prozesse). Im Grunde genommen mein Code wie folgt ausgeführt wird, mit etwa 20 Kindern der Eltern:Wie behandelt man die Parallelität von Python-Multiprocessing-Datenbanken, speziell mit Django?
assorted import statements to get the django environment in the script
from multiprocessing import Pool
from random import random
from time import sleep
def test(child):
x=[]
print child.id
for i in range(100):
print child.id, i
x.append(child.parent.id) #just to hit the DB
return x
if __name__ == '__main__':
parent = Parent.objects.get(id=1)
pool = Pool()
results = []
results = pool.map(test,parent.children.all())
pool.close()
pool.join()
print results
Mit dem Code als solche, erhalte ich intermittierend DatabaseError
s oder PicklingError
s. Ersteres hat normalerweise die Form "missformed database" oder "Verbindung zum MySQL-Server verloren", letzteres ist in der Regel "kann Model.DoesNotExist nicht picken". Sie sind zufällig, treten bei jedem Prozess auf und natürlich ist nichts an der DB selbst falsch. Wenn ich pool = Pool(proccesses=1)
einstelle läuft es dann in einem einzigen Thread ganz gut. Ich gebe auch verschiedene Druckanweisungen ein, um sicherzustellen, dass die meisten tatsächlich ausgeführt werden.
Ich habe auch test
an sich verändert:
def test(child):
x=[]
s= random()
sleep(random())
for i in range(100):
x.append(child.parent.id)
return x
die nur jede Iteration weniger als eine Sekunde vor dem Ausführen Pause macht, und es macht alles in Ordnung. Wenn ich das zufällige Intervall auf ungefähr 500ms heruntersetze, fängt es an zu agieren. Also, wahrscheinlich ein Nebenläufigkeitsproblem, oder? Aber mit nur 4 Prozessen schlagen. Meine Frage ist, wie löse ich das, ohne große Datenmengen vor der Zeit zu machen? Ich habe es sowohl mit SQLite als auch mit MySQL getestet, und beide haben Probleme damit.
Da die Prozesse CPU-gebunden sind, warum dann Verwenden Sie keine 'multiprocessing.Lock', um alle Race-Bedingungen für die Datenbank zu vermeiden? – Bakuriu