2013-11-14 7 views
5

मैं एकाधिक प्रक्रियाओं का उपयोग करके एक प्रोग्राम बनाने का प्रयास कर रहा हूं और त्रुटियों के दौरान मैं सभी तैयार प्रक्रियाओं को साफ़ करना चाहता हूं। नीचे मैंने कुछ छद्म प्रकार कोड लिखा है जो मुझे लगता है कि मुझे क्या करना है, लेकिन मुझे नहीं पता कि सभी प्रक्रियाओं के साथ संवाद करने का सबसे अच्छा तरीका क्या है कि एक त्रुटि हुई है और उन्हें समाप्त करना चाहिए।क्लीन पायथन मल्टीप्रोसेस समाप्ति एक निकास ध्वज पर निर्भर

मुझे लगता है कि मुझे इस तरह की चीज़ों के लिए कक्षाओं का उपयोग करना चाहिए, लेकिन मैं पाइथन के लिए काफी नया हूं इसलिए मैं बस मूल बातें के आसपास अपना सिर लेने की कोशिश कर रहा हूं।

import multiprocessing 
import threading 
import time 

def good_worker(): 
    print "[GoodWorker] Starting" 
    time.sleep(4) 
    print "[GoodWorker] all good" 

def bad_worker(): 
    print "[BadWorker] Starting" 
    time.sleep(2) 
    raise Exception("ups!") 

class MyProcManager(object): 
    def __init__(self): 
     self.procs = [] 
     self.errors_flag = False 
     self._threads = [] 
     self._lock = threading.Lock() 

    def terminate_all(self): 
     with self._lock: 
      for p in self.procs: 
       if p.is_alive(): 
        print "Terminating %s" % p 
        p.terminate() 

    def launch_proc(self, func, args=(), kwargs= {}): 
     t = threading.Thread(target=self._proc_thread_runner, 
          args=(func, args, kwargs)) 
     self._threads.append(t) 
     t.start() 

    def _proc_thread_runner(self, func, args, kwargs): 
     p = multiprocessing.Process(target=func, args=args, kwargs=kwargs) 
     self.procs.append(p) 
     p.start() 
     while p.exitcode is None: 
      p.join() 
     if p.exitcode > 0: 
      self.errors_flag = True 
      self.terminate_all() 

    def wait(self): 
     for t in self._threads: 
      t.join() 

if __name__ == '__main__': 
    proc_manager = MyProcManager() 
    proc_manager.launch_proc(good_worker) 
    proc_manager.launch_proc(good_worker) 
    proc_manager.launch_proc(bad_worker) 
    proc_manager.wait() 
    if proc_manager.errors_flag: 
     print "Errors flag is set: some process crashed" 
    else: 
     print "Everything closed cleanly" 

आप प्रत्येक प्रक्रिया चलाने के लिए एक आवरण धागा, जिसकी समाप्ति के लिए इंतजार कर रहा है की आवश्यकता है:

#imports 

exitFlag = True 

# Function for threads to process 
def url_thread_worker(): 
# while exitFlag: 
    try: 
     # do something 
    except: 
     # we've ran into a problem, we need to kill all the spawned processes and cleanly exit the program 
     exitFlag = False 

def processStarter(): 

    process_1 = multiprocessing.Process(name="Process-1", target=url_thread_worker, args=()) 
    process_2 = multiprocessing.Process(name="Process-2", target=url_thread_worker, args=()) 

    process_1.start() 
    process_2.start() 


if __name__ == '__main__': 
    processStarter() 

अग्रिम

उत्तर

4

धन्यवाद यहाँ मेरी सुझाव है। जब कोई प्रक्रिया समाप्त होती है, तो बाहर निकलने के लिए जांच करें: if> 0, इसका मतलब है कि यह कुछ अनचाहे अपवाद उठाया गया है। अब सभी शेष सक्रिय प्रक्रियाओं को बंद करने के लिए terminate_all() को कॉल करें। रैपर थ्रेड भी समाप्त हो जाएंगे क्योंकि वे प्रक्रिया चलाने पर निर्भर हैं।

इसके अलावा, जब भी आप चाहें proc_manager.terminate_all() को कॉल करने के लिए पूरी तरह से स्वतंत्र हैं। आप किसी भिन्न धागे या कुछ ऐसा कुछ झंडे की जांच कर सकते हैं ..

आशा है कि यह आपके मामले के लिए अच्छा है।

पीएस: बीटीडब्ल्यू .. आपके मूल कोड में आपने वैश्विक निकास_फ्लैग की तरह कुछ किया: आपके पास मल्टीप्रोसेसिंग में "ग्लोबल" एक्जिट_फ्लैग कभी नहीं हो सकता है क्योंकि यह अलग नहीं है क्योंकि आप अलग-अलग मेमोरी रिक्त स्थान के साथ अलग प्रक्रियाओं का उपयोग कर रहे हैं। यह केवल थ्रेडेड वातावरण में काम करता है जहां राज्य साझा किया जा सकता है। यदि आपको मल्टीप्रोसेसिंग में इसकी आवश्यकता है तो आपको प्रक्रियाओं (Pipe and Queue accomplish that) या shared memory objects

+0

यह एक अच्छा उदाहरण है और इससे बहुत मदद मिली है। आपका बहुत बहुत धन्यवाद। –

+1

आपने "आसान हिस्सा" को संभालने का फैसला किया - जब बच्चे मर जाते हैं। लेकिन अगर माता-पिता मर जाए तो क्या होगा? अनाथ प्रक्रियाओं (श्रमिकों) के साथ आपको छोड़ दिया जाएगा। जो, कम से कम मेरे लिए, एक बड़ी समस्या है। –

+0

यह हल करने के लिए एक बहुत ही अलग मामला है और वास्तव में आम नहीं है, IMHO। आपको यह सुनिश्चित करने के लिए अपने सिस्टम को कोड करना चाहिए कि माता-पिता त्रुटियों के प्रति लचीला है और कम से कम, कुछ समस्या होने पर, बच्चे प्रक्रियाओं को समाप्त कर सकते हैं। – abranches

1

के बीच स्पष्ट संचार होना चाहिए यदि आप चाहते हैं कि मूल प्रक्रिया समाप्त होने पर आपके बच्चे को स्वचालित रूप से समाप्त कर दिया जाए; आप उन्हें डेमोनिक बना सकते हैं (.daemon=True.start() से पहले सेट करें) यानी, अगर माता-पिता को कोई त्रुटि पता चलती है; यह अभी निकल सकता है - बच्चों का ख्याल रखा जाएगा।

यदि आप चाहते हैं कि बच्चे खुद के बाद सफाई करें; आप use multiprocessing.Event() as a global flag:

import multiprocessing 

def event_func(event): 
    print '\t%r is waiting' % multiprocessing.current_process() 
    event.wait() 
    print '\t%r has woken up' % multiprocessing.current_process() 

if __name__ == '__main__': 
    event = multiprocessing.Event() 

    processes = [multiprocessing.Process(target=event_func, args=(event,)) 
       for i in range(5)] 

    for p in processes: 
     p.start() 

    print 'main is sleeping' 
    time.sleep(2) 

    print 'main is setting event' 
    event.set() 

    for p in processes: 
     p.join() 
संबंधित मुद्दे