2015-05-12 7 views
8

मैं multiprocessing.Manager() ऑब्जेक्ट का उपयोग करना चाहता हूं ताकि मैं एक सर्वर से जानकारी भेजने के लिए एक कार्यकर्ता से प्रबंधक को जानकारी भेज सकूं। मेरे पास डिस्क पर पीडीएफ लिखने के लगभग 10 उदाहरण हैं। मैं फिर मल्टीप्रोसेसिंग पैकेज में प्रबंधक ऑब्जेक्ट का उपयोग अपने एस 3 बाल्टी को भेजने के लिए करना चाहता था क्योंकि मैं स्थानीय सामग्री उत्पादन को रोकना नहीं चाहता हूं।उचित रूप से एक मल्टीप्रोसेसिंग। प्रबंधक कस्टम ऑब्जेक्ट को डिजाइन करना

तो मैं सोच रहा था कि क्या मैं कस्टम मैनेजर ऑब्जेक्ट बनाता हूं, क्या यह ऐसा करने का सही तरीका है? प्रबंधक ऑब्जेक्ट को सबमिट की गई प्रत्येक प्रक्रिया कतारबद्ध होगी? या यदि मैं एकाधिक अपलोड कहता हूं, तो क्या प्रबंधक कुछ कॉल छोड़ देगा?

नीचे मैं क्या कर की सोच रहा हूँ का एक नमूना कोड है:

from multiprocessing.managers import BaseManager 

class UploadClass(object): 
    def upload(self, filePath, params, destUrl): 
     # do stuff 
     return results 

class MyManager(BaseManager): 
    pass 

MyManager.register('uploads', UploadClass) 

if __name__ == '__main__': 
    manager = MyManager() 
    manager.start() 
    upload = manager.uploads() 
    # do this wait for completion or do they perform this async 
    print upload.upload(r"<path>", {...}, "some url") 
    print upload.upload(r"<path>", {...}, "some url") 
+0

बस स्पष्ट करने के लिए: आप दस अलग-अलग प्रक्रियाएं चाहते हैं (एक ही पायथन लिपि के इन अनूठे उदाहरण हैं, या सिर्फ मल्टीप्रोसेसिंग। प्रोसेस उदाहरण एक स्क्रिप्ट के अंदर पैदा हुए हैं?), जो सभी डिस्क पर पीडीएफ लिखते हैं। एक बार जब वे लिखते हैं, तो प्रत्येक इंस्टेंस फ़ाइल के पथ को एक 'मल्टीप्रोसेसिंग। प्रबंधक' पर भेज देगा, जिसे फ़ाइलों को एक समय में अपलोड करना चाहिए (जिसका मतलब कोई समानांतर अपलोड नहीं है)। क्या वह सही है? – dano

+0

इसके अलावा, क्या आप अपलोड प्रक्रिया से परिणाम प्राप्त करने की परवाह करते हैं? या आप बस पृष्ठभूमि में अपलोड को बंद करना चाहते हैं और इसके बारे में भूल जाओ? – dano

+0

@ डैनो - प्रक्रिया को सही तरीके से काम करने के लिए प्रक्रिया से कुछ प्रकार का संदेश वापस पाने में मददगार होगा। –

उत्तर

2

सीधे आपके कुछ प्रश्नों के उत्तर देने के लिए:

प्रत्येक प्रक्रिया प्रबंधक वस्तु को प्रस्तुत पंक्तिबद्ध हो जाएगा?

Manager सर्वर ने एक नया धागा आने वाली प्रत्येक अनुरोध को पूरा करने spawns, तो अपने सभी अनुरोधों तुरन्त संभाला जा रहा प्रारंभ होगा।

def serve_forever(self): 
    ''' 
    Run the server forever 
    ''' 
    current_process()._manager_server = self 
    try: 
     try: 
      while 1: 
       try: 
        c = self.listener.accept() 
       except (OSError, IOError): 
        continue 
       t = threading.Thread(target=self.handle_request, args=(c,)) 
       t.daemon = True 
       t.start() 
     except (KeyboardInterrupt, SystemExit): 
      pass 
    finally: 
     self.stop = 999 
     self.listener.close() 

अगर मैं एकाधिक अपलोड फोन, प्रबंधक कॉल के कुछ छोड़ देंगे: आप multiprocessing/managers.py के इस के अंदर देख सकते हैं?

नहीं, कोई भी कॉल नहीं छोड़ी जाएगी।

# do this wait for completion or do they perform this async 
print upload.upload(r"<path>", {...}, "some url") 
print upload.upload(r"<path>", {...}, "some url") 

upload.upload के लिए कॉल तुल्यकालिक हो जाएगा दोनों; वे UploadClass.upload तक वापस नहीं आ जाएंगे। हालांकि, यदि आपके पास upload.upload को समेकित एकाधिक स्क्रिप्ट/थ्रेड/प्रक्रियाएं थीं, तो प्रत्येक अद्वितीय कॉल Manager सर्वर प्रक्रिया में अपने स्वयं के धागे के साथ समवर्ती रूप से हो रही होगी।

और अपने सबसे सबसे महत्वपूर्ण प्रश्न:

इस ऐसा करने के लिए उचित तरीका है?

मैं नहीं कहूंगा, अगर मैं सही तरीके से प्रश्न समझता हूं। आप बस एक स्क्रिप्ट है, और फिर उस एक स्क्रिप्ट के अंदर दस multiprocessing.Process उदाहरणों अंडे पीडीएफ़ को लिखने के लिए है, तो आप सिर्फ एक और multiprocessing.Process अपलोड संभाल करने का उपयोग करना चाहिए:

def upload(self, q): 
    for payload in iter(q.get, None): # Keep getting from the queue until a None is found 
     filePath, params, destUrl = payload 
     # do stuff 

def write_pdf(pdf_file_info, q): 
    # write a pdf to disk here 
    q.put((filepath, params, destUrl)) # Send work to the uploader 
    # Move on with whatever comes next. 

if __name__ == '__main__': 
    pdf_queue = multiprocessing.Queue() 

    # Start uploader 
    upload_proc = multiprocessing.Process(upload, args=(pdf_queue,)) 
    upload_proc.start() 

    # Start pdf writers 
    procs = [] 
    for pdf in pdfs_to_write: 
     p = multiprocessing.Process(write_pdf, args=(pdf, pdf_queue)) 
     p.start() 
     p.append(procs) 

    # Wait for pdf writers and uploader to finish. 
    for p in procs: 
     p.join() 
    pdf_queue.put(None) # Sending None breaks the for loop inside upload 
    upload_proc.join() 

आप वास्तव में समवर्ती के साथ ठीक कर रहे हैं अपलोड, तो अलग upload प्रक्रिया बिल्कुल अलग करने की आवश्यकता नहीं है - बस पीडीएफ लेखन प्रक्रियाओं से सीधे अपलोड करें।

यह आपके प्रश्न से बताना मुश्किल है यदि यह वही है जो आप कर रहे हैं। एक बार जब आप स्पष्टीकरण देते हैं, तो मैं आपके अंतिम उपयोग-मामले में फिट होने के लिए इस अंतिम टुकड़े को समायोजित कर दूंगा।

+0

क्यों मुख्य प्रक्रिया से सीधे डालने की बजाए डेटा को कतार में डेटा डालने की प्रक्रिया होती है? – sirfz

+0

@Sir_FZ ओपी ने कहा कि उनके पास पीडीएफ लिखने के कई उदाहरण थे: * "मेरे पास डिस्क पर पीडीएफ लिखने के लगभग 10 उदाहरण हैं" *। ऐसे में कई कर्मचारी हैं जो वस्तुओं को समानांतर में कतार में डालते हैं। – dano

+0

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

संबंधित मुद्दे