जब मुख्य कार्यक्रम समाप्त होता है तो किसी धागे को कैसे समाप्त किया जाए?


85

अगर मैं एक अनंत लूप में एक धागा है, तो इसे समाप्त करने के लिए जब मुख्य कार्यक्रम समाप्त होता है (उदाहरण के लिए, मैं जब प्रेस एक तरीका है Ctrl+ C)?

जवाबों:


46

इस प्रश्न की जाँच करें। सही उत्तर में थ्रेड को सही तरीके से समाप्त करने के तरीके के बारे में बहुत व्याख्या है: क्या पायथन में थ्रेड को मारने का कोई तरीका है?

कीबोर्ड इंटरप्ट सिग्नल (ctrl + c) पर थ्रेड स्टॉप बनाने के लिए आप बाहर निकलने से पहले "KeyboardInterrupt" और क्लीनअप अपवाद को पकड़ सकते हैं। इस कदर:

try:
    start_thread()  
except (KeyboardInterrupt, SystemExit):
    cleanup_stop_thread()
    sys.exit()

इस तरह से आप नियंत्रित कर सकते हैं कि जब भी कार्यक्रम अचानक समाप्त हो जाए तो क्या करें।

आप अंतर्निहित सिग्नल मॉड्यूल का उपयोग भी कर सकते हैं जो आपको सिग्नल हैंडलर सेटअप करने देता है (अपने विशिष्ट मामले में संकेत): http://docs.python.org/library/signal.html


उत्तर के लिए आपका बहुत - बहुत धन्यवाद। मैंने सवाल को सही तरीके से नहीं बताया होगा। उस प्रश्न में दिए गए उदाहरण में थ्रेड के स्टॉप () फ़ंक्शन को निष्पादित करना अभी भी आवश्यक था। जब मैं किसी प्रोग्राम को ctrl + C द्वारा असामान्य रूप से समाप्त करता हूं, तो ऐसा नहीं हो सकता। तो, मेरा सवाल थोड़ा सा है, "मैं कैसे कहूँ मिथ्रेड.स्टॉप () फंकियन अगर मुख्य धागा प्रवाह बाधित हो जाता है"
23

1
क्या cleanup_stop_thread()एक वैश्विक कार्य है जिसका मैं उपयोग कर सकता हूं? या क्या मुझे इसे लागू करने की आवश्यकता है?
alper

@alper, मुझे लगता है कि शायद यह केवल एक उदाहरण था जो कुछ को लागू करना संभव है। आपको उस पर अमल करना चाहिए
लियोनार्डो रिक

98

यदि आप अपने कार्यकर्ता धागे को डेमॉन थ्रेड बनाते हैं, तो वे मर जाएंगे जब आपके सभी गैर-डायमन थ्रेड्स (जैसे मुख्य धागा) बाहर निकल जाते हैं।

http://docs.python.org/library/threading.html#threading.Thread.daemon


4
सरल और सटीक उत्तर के लिए धन्यवाद, डिफ़ॉल्ट थ्रेडिंग। थ्रेडन डेमन स्थिति isDaemon()गलत है, इसे सही द्वारा सेट करें setDaemon(True)
टोंग

3
यह सवाल का जवाब देता है और सिर्फ काम करता है। ऑप ने यह नहीं पूछा कि सामान्य रूप से थ्रेड्स को कैसे बाहर निकालना है।
जोहान्स ओवरमैन

1
isDaemon()और setDaemon()वर्ष getters / setters हैं (ऊपर लिंक दस्तावेज़ के अनुसार), बस का उपयोग daemon=Trueमेंthreading.Thread()
fabio.sang

1
ध्यान दें कि डेमन थ्रेड्स का उपयोग करने से अन्य समस्याएं हो सकती हैं और संभवतः वह नहीं है जो आप यहां चाहते हैं: stackoverflow.com/questions/20596918/…
Doopy

डेमन थ्रेड्स का उपयोग करने से बचें और थ्रेड्स को आसानी से मारें, देखें stackoverflow.com/questions/58910372/…
Pat-Laugh

15

उप-धागे को डेमन-थ्रेड के रूप में सक्षम करने का प्रयास करें।

उदाहरण के लिए:

सिफारिश की:

from threading import Thread

t = Thread(target=<your-method>)
t.daemon = True  # This thread dies when main thread (only non-daemon thread) exits.
t.start()

पंक्ति में:

t = Thread(target=<your-method>, daemon=True).start()

पुराना API:

t.setDaemon(True)
t.start()

अपने मुख्य थ्रेड समाप्त ( "यानी जब मैं प्रेस जब Ctrl+ C"), अन्य थ्रेड भी ऊपर दिए गए निर्देशों के हाथों मारे गए हो जाएगा।


1
ध्यान दें कि डेमन थ्रेड्स का उपयोग करने से अन्य समस्याएं हो सकती हैं और शायद आप यहां क्या नहीं चाहते हैं: stackoverflow.com/questions/20596918/…
Doopy

12

"समाप्ति" फ़ंक्शन को पंजीकृत करने के लिए पायथन की मानक लाइब्रेरी के एटैक्सिट मॉड्यूल का उपयोग करें जो मुख्य धागे के किसी भी यथोचित "साफ" समाप्ति पर (मुख्य थ्रेड पर) कॉल करते हैं, जैसे कि बिना किसी अपवाद के अपवाद KeyboardInterrupt। इस तरह के टर्मिनेशन फंक्शन (मुख्य थ्रेड में अनिवार्य रूप से!) stopआपको किसी भी फ़ंक्शन को कॉल करने की आवश्यकता होती है; साथ में एक धागा सेट करने की संभावना के साथ daemon, जो आपको सिस्टम की कार्यक्षमता को ठीक से डिजाइन करने के लिए उपकरण देता है जो आपको चाहिए।


ध्यान दें कि इस दृष्टिकोण ने 2.6.5 से पहले पायथन संस्करणों में डेमनीकृत थ्रेड्स की आवश्यकता के बिना काम किया, stackoverflow.com/questions/3713360/… का उत्तर देखें । यह दुर्भाग्यपूर्ण IMHO है, क्योंकि शटडाउन के दौरान डेमन थ्रेड्स अजगर 3.4 ( bugs.python.org/issue19466 ) से पहले एक गड़बड़ है । यदि आप रुकते हैं और अपने डेक्स थ्रेड्स को अपने एटैक्सिट हैंडलर्स में शामिल करते हैं, तो सभी को आपके थ्रेड टेडडाउन को सीरीज़ करने की लागत (शायद तुच्छ) पर ठीक होना चाहिए।
नीलेंमरिस

विदित हो कि atexit.register()पायथन मॉड्यूल्स में पोस्ट-पॉन्ड कॉल के कारण अजीब चीजें हो सकती हैं , जिससे आपकी समाप्ति प्रक्रिया समाप्त हो सकती है multiprocessing। मैं इस समस्या से जूझ रहा हूं Queueऔर daemonथ्रेड से निपटने में : "ईओएफ त्रुटि" प्रोग्राम एग्जिट पर मल्टीप्रोसेसिंग क्यू और थ्रेड का उपयोग करते हुए
डेलगन

जाहिरा तौर पर पायथन के आधुनिक संस्करणों में, जैसे कि 3.7.4+, atexitगैर-डेमन थ्रेड जीवित होने पर हैंडलर नहीं कहलाते हैं और मुख्य धागा बाहर निकलता है। देखें जब atexit का उपयोग कर धागे समाप्त करने के लिए स्क्रिप्ट से बाहर निकलें पर अटक
मार्टीन्यू

9

यदि आप किसी थ्रेड को जैसे - myThread = Thread(target = function)- और तब करते हैं myThread.start(); myThread.join()। जब CTRL-C शुरू किया जाता है, तो मुख्य धागा बाहर नहीं निकलता है क्योंकि यह उस अवरुद्ध myThread.join()कॉल पर प्रतीक्षा कर रहा है । इसे ठीक करने के लिए, बस .join () कॉल पर टाइमआउट में डालें। आपकी इच्छानुसार समय समाप्त हो सकता है। यदि आप इसे अनिश्चित काल तक इंतजार करना चाहते हैं, तो बस 99999 की तरह, वास्तव में लंबे समय के लिए रखा गया है myThread.daemon = True। मुख्य थ्रेड (गैर-डेमन) से बाहर निकलने पर सभी थ्रेड्स बाहर निकलने के लिए ऐसा करना भी अच्छा अभ्यास है।


myThread.daemon = Trueइस समस्या का एक अद्भुत समाधान है।
Brannon

5
@ ब्रनन .daemon=Trueएक ठोस समाधान नहीं है। एक स्पष्टीकरण के लिए इस धागे की जाँच करें: stackoverflow.com/a/20598791/5562492
ओडिसी

2

डेमन थ्रेड्स को असामयिक रूप से मार दिया जाता है, इसलिए किसी भी अंतिम निर्देशों को निष्पादित नहीं किया जाता है। जाँच करने के लिए एक संभावित समाधान अनंत लूप के बजाय मुख्य धागा जीवित है।

पायथन 3 के लिए जैसे:

while threading.main_thread().isAlive():
    do.you.subthread.thing()
gracefully.close.the.thread()

देखें कि क्या मुख्य धागा अभी भी दूसरे धागे से जीवित है

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.