2013-08-15 4 views
10

तो, मैं एक एप्लिकेशन लिखने की कोशिश कर रहा हूं जो डीजेंगो को अपने ओआरएम के रूप में उपयोग करता है, क्योंकि इसे दोनों दृश्यों के प्रसंस्करण और फ्रंट-एंड का उपयोग करने में आसान कुछ करने की आवश्यकता होगी। यह मुख्य कार्यक्षमता डाटाबेस में एक उच्च-सीपीयू प्रक्रिया (मूल रूप से मोंटे कार्लो सिमुलेशन) में डेटा प्रोसेसिंग करेगा और मैं मल्टीप्रोसेसिंग को कार्यान्वित करना चाहता हूं, विशेष रूप से पूल (मुझे 4 प्रक्रियाएं मिलती हैं) का उपयोग करना। असल में मेरे कोड इस तरह से चलाता है, माता-पिता के बारे में 20 बच्चों के साथ:पाइथन मल्टीप्रोसेसिंग डेटाबेस समेकन को कैसे संभालें, विशेष रूप से 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 

जैसे कोड के साथ, मैं रुक-रुक कर DatabaseError या PicklingError रों मिलता है। पूर्व आमतौर पर "विकृत डेटाबेस" या "MySQL सर्वर से खोए गए कनेक्शन" के रूप में होते हैं, बाद वाले आमतौर पर "मॉडल को नहीं चुन सकते हैं। 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 

कौन सा बस प्रत्येक यात्रा को चलाने से पहले एक दूसरे से कम थामने है, और यह सब कुछ ठीक कर देता है। अगर मुझे यादृच्छिक अंतराल लगभग 500ms तक मिलता है तो यह अभिनय करना शुरू कर देता है। तो, शायद एक सहमति समस्या, है ना? लेकिन केवल 4 प्रक्रियाओं को मारने के साथ। मेरा सवाल यह है कि मैं समय से पहले डेटा के बड़े डंप किए बिना इसे कैसे हल करूं? मैंने इसे SQLite और MySQL दोनों के साथ परीक्षण किया है, और दोनों को इसके साथ परेशानी हो रही है।

+0

के बाद से प्रक्रियाओं सीपीयू बाध्य कर रहे हैं, तो क्यों डेटाबेस में सभी दौड़ स्थितियों से बचने के लिए आप 'multiprocessing.Lock' का उपयोग नहीं करते हैं? – Bakuriu

उत्तर

7

ठीक है, इसलिए मैंने निर्धारित किया (एक दोस्त की मदद से) कि मुद्दा यह है कि django सभी प्रक्रियाओं के लिए एक ही डेटाबेस कनेक्शन का उपयोग कर रहा है। आम तौर पर, जब आपके समवर्ती डीबी अनुरोध होते हैं, तो वे या तो एक ही धागे में होते हैं (जिस स्थिति में जीआईएल में प्रवेश होता है) या वे अलग-अलग धागे पर होते हैं, इस मामले में डीजेंगो विभिन्न डेटाबेस कनेक्शन बनाता है। लेकिन मल्टीप्रोसेसिंग के साथ, पायथन सबकुछ की गहरी चीजें बनाता है, इसलिए यह सबप्रोसेसेस के लिए एक ही डेटाबेस कनेक्शन पास कर रहा है, और फिर वे टूटने तक एक-दूसरे पर कदम उठाते हैं।

समाधान प्रत्येक उपप्रोसेस (जो अपेक्षाकृत तेज़ है) के भीतर से एक नया डीबी कनेक्शन ट्रिगर करना है।

from django import db 
... 
def sub_process(): 
    db.close_connection() 
    #the rest of the sub_process' routines 

#code that calls sub_process with the pool 

उस रेखा से आगे और आगे निकल गया, और उस रेखा से नहीं, और निश्चित रूप से सबकुछ ठीक करता है।

+1

धन्यवाद! मैं पहले थ्रेडिंग का उपयोग कर रहा था और जब मैंने मल्टीप्रोसेसिंग का उपयोग शुरू किया तो समस्याएं आईं। दो मामलों के बीच आपकी व्याख्या ने मेरा दिन बनाया। – Mikuz

3

असल में मैं हाल ही में एक ही समस्याओं मिल गया है, और इस पोस्ट देखें: Django multiprocessing and database connections ... और बस subprocesses में कनेक्शन बंद करने आपरेशन आह्वान:

from django.db import connection 
connection.close() 
संबंधित मुद्दे