Итак, я пытаюсь написать приложение, которое использует django как свой ORM, так как ему нужно будет сделать некоторые за кулисами и простой в использовании интерфейс. Это основная функциональность будет обрабатывать данные, которые в базе данных, в высоко-процессорном процессе (в основном monte carlo simulations), и я хочу реализовать многопроцессорность, в частности, используя Pool (я получаю 4 процесса). В основном мой код работает примерно так: около 20 детей родителя:
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
С кодом как таковым я получаю прерывистый DatabaseError
или PicklingError
s. Первые обычно имеют форму "искаженная база данных" или "потерянное соединение с сервером MySQL", последние обычно "не могут рассортировать model.DoesNotExist". Они случайны, происходят с любым процессом, и, конечно, нет ничего плохого в самой БД. Если я устанавливаю pool = Pool(proccesses=1)
, тогда он запускается в одном потоке просто отлично. Я также использую различные инструкции для печати, чтобы убедиться, что большинство из них действительно запущено.
Я также менял test
на:
def test(child):
x=[]
s= random()
sleep(random())
for i in range(100):
x.append(child.parent.id)
return x
Это просто делает каждую итерацию паузой менее секунды, прежде чем запускать, и делает все в порядке. Если я получу случайный интервал до примерно 500 мс, он начнет действовать. Итак, вероятно проблема concurrency, не так ли? Но только с 4 процессами. Мой вопрос заключается в том, как решить эту проблему, не дав больших дампов данных раньше времени? Я протестировал его как с SQLite, так и с MySQL, и у обоих есть проблемы с этим.