2014-04-21 9 views
18

में इसका उत्तर Android, Objective C और C++ से पहले दिया गया है, लेकिन स्पष्ट रूप से पायथन के लिए नहीं। मैं विश्वसनीय रूप से यह निर्धारित कैसे करूं कि वर्तमान धागा मुख्य धागा है या नहीं? मैं कुछ दृष्टिकोणों के बारे में सोच सकता हूं, जिनमें से कोई भी वास्तव में मुझे संतुष्ट नहीं करता है, क्योंकि यह threading.MainThread की तुलना में यह आसान हो सकता है।जांचें कि वर्तमान धागा मुख्य धागा है, पाइथन

चेक धागा नाम

मुख्य थ्रेड इस तरह threading.py में instantiated है:

Thread.__init__(self, name="MainThread") 

तो एक

if threading.current_thread().name == 'MainThread' 

कर सकता है, लेकिन इस नाम तय हो गई है? अन्य कोड मैंने देखा है कि MainThread धागे के नाम में कहीं भी निहित है।

स्टोर शुरू धागा

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

क्या ऐसा करने का एक और संक्षिप्त तरीका है?

उत्तर

30

threading.current_thread().name == 'MainThread' के साथ समस्या यह है कि एक हमेशा क्या कर सकते हैं:

threading.current_thread().__class__.__name__ == '_MainThread' 

कहा करने के बाद कि, एक अभी भी चालाकी से ऐसा कर सकते हैं:

threading.current_thread().name = 'MyName' 
assert threading.current_thread().name == 'MainThread' # will fail 

शायद निम्नलिखित अधिक ठोस है

threading.current_thread().__class__.__name__ = 'Grrrr' 
assert threading.current_thread().__class__.__name__ == '_MainThread' # will fail 

लेकिन यह विकल्प अभी भी बेहतर लगता है; "after all, we're all consenting adults here."

अद्यतन:

अजगर 3.4 threading.main_thread() शुरू की जो ऊपर की तुलना में बहुत खूबसूरत है:

assert threading.current_thread() == threading.main_thread() 

अद्यतन 2:

नीचे टिप्पणी में उल्लेख किया user1300959 द्वारा, , एक और व्यवहार्य और साफ विकल्प है:

isinstance(threading.current_thread(), threading._MainThread) 
+14

'isinstance (threading.current_thread(), threading._Main थ्रेड)'? – iurii

+0

यह टिप्पणी अपनी प्रतिक्रिया हो सकती है :) – jonny

+1

क्या '_MainThread' के बारे में कोई दस्तावेज है? क्या यह एक विशिष्ट कार्यान्वयन का केवल एक हिस्सा है? – jonny

2

यदि मेरे जैसे, संरक्षित विशेषताओं तक पहुंचने से आपको हेबी-जीबी मिलती है, तो आप का उपयोग करने के लिए suggested के रूप में उपयोग करने का विकल्प चाह सकते हैं। उस मामले में, आप, तथ्य यह है कि only the Main Thread can handle signals शोषण तो निम्नलिखित काम कर सकते हैं हो सकता है:

import signal 
def is_main_thread(): 
    try: 
     # Backup the current signal handler 
     back_up = signal.signal(signal.SIGINT, signal.SIG_DFL) 
    except ValueError: 
     # Only Main Thread can handle signals 
     return False 
    # Restore signal handler 
    signal.signal(signal.SIGINT, back_up) 
    return True 

के रूप में @ user4815162342 द्वारा बताया संभावित समस्या को हल करने अपडेट किया गया।

+1

इस उत्तर के अच्छे इरादे हैं, लेकिन प्रस्तुत कोड में एक समस्या है जो इसे उत्पादन के लिए उपयुक्त बनाता है। 'Is_main_thread' फ़ंक्शन का वास्तव में' सिगिनट 'व्यवहार को पायथन के सामान्य' signal.default_int_handler' के बजाय libc ''SIG_DFL' में बदलने का बुरा दुष्प्रभाव है। दूसरे शब्दों में, पाइथन ** is_main_thread() 'के आवेदक के बाद ** वही व्यवहार नहीं करेगा जो सत्य लौटाता है। इसे चलाने के बाद,^सी दबाकर अब 'कीबोर्डइंटरप्ट' के साथ प्रक्रिया को बाधित नहीं किया जाएगा (जो एक स्टैक ट्रेस प्रिंट करता है और 'आखिरकार' ब्लॉक चलाता है), लेकिन तुरंत बाहर निकल जाएगा। – user4815162342

+0

@ user4815162342 इसे इंगित करने के लिए धन्यवाद। वर्तमान सिग्नल हैंडलर का बैकअप लेना संभव है, और लौटने से पहले इसे बहाल करना संभव है, इस प्रकार सिग्नल हैंडलर को बरकरार रखना। – asherbar

3

यहाँ जवाब वर्ष और/या बुरा कर रहे हैं, तो यहाँ एक मौजूदा समाधान है:

if threading.current_thread() is threading.main_thread(): 
    ... 

इस विधि पायथन के बाद से 3.4+ उपलब्ध है।

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