2009-09-28 17 views
35

मैं अपने पूरे पायथन एप्लिकेशन को इसके धागे से कैसे निकाल सकता हूं? sys.exit() केवल उस धागे को समाप्त करता है जिसमें इसे कहा जाता है, इसलिए यह कोई मदद नहीं है।पाइथन थ्रेड से पूरे एप्लिकेशन से कैसे बाहर निकलें?

मैं os.kill() समाधान का उपयोग नहीं करना चाहता, क्योंकि यह बहुत साफ नहीं है।

उत्तर

33

यदि मुख्य के अलावा आपके सभी धागे डिमन्स हैं, तो सबसे अच्छा तरीका आम तौर पर thread.interrupt_main() होता है - कोई धागा इसका उपयोग मुख्य धागे में KeyboardInterrupt बढ़ाने के लिए कर सकता है, जो आम तौर पर मुख्य धागे से उचित रूप से साफ निकास का कारण बन सकता है (मुख्य धागे में फाइनलाइजर्स को बुलाया जा रहा है, आदि)।

बेशक

, अगर कुछ गैर डेमॉन सूत्र में इस परिणाम पूरी प्रक्रिया को जीवित रखने के लिए, आप os._exit साथ अनुसरण करने के लिए के रूप में मार्क की सिफारिश की जरूरत है - लेकिन मैं देखना चाहते हैं कि एक kill -9 अंतिम उपाय के रूप (एक तरह से की तरह; -) क्योंकि यह चीजों को पूरी तरह से समाप्त करता है (फाइनल नहीं चलाता है, जिसमें try/finally ब्लॉक, with ब्लॉक, atexit फ़ंक्शन इत्यादि शामिल हैं)।

+0

आपका लिंक मर चुका है। – OrangeDog

28

संक्षिप्त उत्तर: os._exit का उपयोग करें। उदाहरण के साथ

लांग जवाब:

मैं yanked और थोड़ा a tutorial on DevShed से एक सरल सूत्रण उदाहरण संशोधित:

import threading, sys, os 

theVar = 1 

class MyThread (threading.Thread): 

    def run (self): 

     global theVar 
     print 'This is thread ' + str (theVar) + ' speaking.' 
     print 'Hello and good bye.' 
     theVar = theVar + 1 
     if theVar == 4: 
      #sys.exit(1) 
      os._exit(1) 
     print '(done)' 

for x in xrange (7): 
    MyThread().start() 

आप sys.exit(1) बाहर टिप्पणी की रहती है, तो स्क्रिप्ट तीसरे धागा प्रिंट आउट के बाद मर जाएगा। यदि आप sys.exit(1) का उपयोग करते हैं और os._exit(1) पर टिप्पणी करते हैं, तो तीसरा धागा प्रिंट (done) प्रिंट करता है, और प्रोग्राम सभी सात धागे से चलता है।

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

11

thread.interrupt_main() का उपयोग कुछ परिस्थितियों में मदद नहीं कर सकता है। वर्तमान आदेश से बाहर निकलने या इनपुट लाइन को साफ करने के लिए KeyboardInterrupt s अक्सर कमांड लाइन अनुप्रयोगों में उपयोग किया जाता है।

इसके अतिरिक्त, os._exit आपके कोड में finally ब्लॉक चलाने के बिना तुरंत प्रक्रिया को मार देगा, जो खतरनाक हो सकता है (उदाहरण के लिए फ़ाइलें और कनेक्शन बंद नहीं होंगे)।

जो समाधान मैंने पाया है वह मुख्य थ्रेड में सिग्नल हैंडलर पंजीकृत करना है जो एक कस्टम अपवाद उठाता है। सिग्नल को आग लगाने के लिए पृष्ठभूमि धागे का प्रयोग करें।

import signal 
import os 
import threading 
import time 


class ExitCommand(Exception): 
    pass 


def signal_handler(signal, frame): 
    raise ExitCommand() 


def thread_job(): 
    time.sleep(5) 
    os.kill(os.getpid(), signal.SIGUSR1) 


signal.signal(signal.SIGUSR1, signal_handler) 
threading.Thread(target=thread_job).start() # thread will fire in 5 seconds 
try: 
    while True: 
     user_input = raw_input('Blocked by raw_input loop ') 
     # do something with 'user_input' 
except ExitCommand: 
    pass 
finally: 
    print('finally will still run') 

संबंधित प्रश्न:

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