Quindi, sto provando a scrivere un'applicazione che usa django come ORM, dal momento che entrambi dovranno fare un po 'di elaborazione dietro le quinte e un front-end facile da usare. La sua funzionalità principale sarà l'elaborazione dei dati presenti nel database, in un processo ad alta CPU (fondamentalmente simulazioni di monte carlo) e voglio implementare il multiprocessing, in particolare usando Pool (ho 4 processi). Fondamentalmente il mio codice viene eseguito in questo modo, con circa 20 bambini del genitore:Come gestire la concorrenza del database di multiprocessing Python, in particolare con 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
con il codice in quanto tale, ottengo intermittente DatabaseError
s o PicklingError
s. I primi sono solitamente di tipo "database malformato" o "connessione persa con il server MySQL", questi ultimi di solito "non possono decapitare model.DoesNotExist". Sono casuali, si verificano con qualsiasi processo e, naturalmente, non c'è nulla di sbagliato nel DB stesso. Se imposto pool = Pool(proccesses=1)
allora viene eseguito, in un singolo thread, bene. Inserisco anche varie dichiarazioni di stampa per assicurarmi che la maggior parte di esse sia effettivamente in esecuzione.
Ho anche stanno cambiando test
a:
def test(child):
x=[]
s= random()
sleep(random())
for i in range(100):
x.append(child.parent.id)
return x
Il che fa solo ogni iterazione pausa meno di un secondo prima di eseguire, e rende tutto bene. Se ottengo l'intervallo casuale a circa 500 ms, inizia a comportarsi. Quindi, probabilmente un problema di concorrenza, giusto? Ma con solo 4 processi che colpiscono. La mia domanda è come posso risolvere questo senza fare grandi discariche di dati in anticipo? L'ho provato con SQLite e MySQL, ed entrambi hanno problemi con questo.
Dal momento che i processi sono CPU-bound, allora perché non usi un 'multiprocessing.Lock' per evitare tutte le condizioni di gara nel database? – Bakuriu