Tak więc, próbuję napisać aplikację, która używa django jako ORM, ponieważ będzie ona wymagała zarówno przetwarzania za kulisami, jak i łatwego w użyciu front-endu. Jego podstawową funkcjonalnością będzie przetwarzanie danych znajdujących się w bazie danych, w procesie wysokoprocesorowym (w zasadzie symulacje Monte Carlo) i chcę zaimplementować proces wieloprocesowy, w szczególności przy użyciu puli (otrzymuję 4 procesy). Zasadniczo mój kod działa jak ten, z około 20 dzieci dominującej:Jak obsługiwać współbieżność bazy danych wieloprocesorowych Pythona, w szczególności z 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
z Kodeksem jako takiego, mam przerywany DatabaseError
s lub PicklingError
s. Te pierwsze mają zwykle postać "zniekształconej bazy danych" lub "utraconego połączenia z serwerem MySQL", te ostatnie są zwykle "nie mogą podnosić modelu.DoesNotExist". Są przypadkowe, występują w dowolnym procesie i oczywiście nie ma nic złego w samym DB. Jeśli ustawię pool = Pool(proccesses=1)
, to działa, w jednym wątku po prostu dobrze. Dodaję też różne instrukcje drukowania, aby upewnić się, że większość z nich faktycznie działa.
ja również się zmienia test
do:
def test(child):
x=[]
s= random()
sleep(random())
for i in range(100):
x.append(child.parent.id)
return x
który właśnie sprawia, że każda iteracja wstrzymać mniej niż sekundę przed uruchomieniem, a to sprawia, że wszystko w porządku. Jeśli otrzymam losowy interwał w dół do około 500ms, zacznie działać. Więc prawdopodobnie problem współbieżności, prawda? Ale tylko 4 procesy uderzają. Moje pytanie brzmi: jak rozwiązać ten problem bez dokonywania dużych zrzutów danych z wyprzedzeniem? Przetestowałem go zarówno z SQLite, jak i MySQL, i oba mają z tym problem.
Ponieważ procesy CPU-bound, to dlaczego czy nie używasz opcji 'multiplerocessing.Lock', aby uniknąć wszystkich warunków wyścigu do bazy danych? – Bakuriu