मुझे धागे को सही ढंग से समाप्त करने की आवश्यकता नहीं है, या इसे "समाप्त" कमांड का जवाब देना है। मैं शुद्ध C ++ 11 का उपयोग करके थ्रेड को जबरदस्ती समाप्त करने में रुचि रखता हूं।
मुझे धागे को सही ढंग से समाप्त करने की आवश्यकता नहीं है, या इसे "समाप्त" कमांड का जवाब देना है। मैं शुद्ध C ++ 11 का उपयोग करके थ्रेड को जबरदस्ती समाप्त करने में रुचि रखता हूं।
जवाबों:
आप std::terminate()
किसी भी थ्रेड से कॉल कर सकते हैं और जिस थ्रेड का आप ज़िक्र कर रहे हैं वह बलपूर्वक समाप्त हो जाएगा।
आप ~thread()
लक्ष्य थ्रेड के ऑब्जेक्ट पर, बिना किसी हस्तक्षेप के join()
और न ही detach()
उस ऑब्जेक्ट पर निष्पादित होने की व्यवस्था कर सकते हैं । इसका विकल्प 1 जैसा ही प्रभाव पड़ेगा।
आप एक अपवाद डिज़ाइन कर सकते हैं जिसमें एक विध्वंसक होता है जो एक अपवाद को फेंकता है। और फिर इस अपवाद को फेंकने के लिए लक्ष्य थ्रेड की व्यवस्था करें जब इसे बलपूर्वक समाप्त किया जाए। इस पर एक मुश्किल हिस्सा इस अपवाद को फेंकने के लिए लक्ष्य धागा प्राप्त कर रहा है।
विकल्प 1 और 2 इंट्रा-प्रोसेस संसाधनों को लीक नहीं करते हैं, लेकिन वे हर थ्रेड को समाप्त करते हैं ।
विकल्प 3 संभवतः संसाधनों को लीक करेगा, लेकिन आंशिक रूप से सहकारी है कि लक्ष्य थ्रेड को अपवाद को फेंकने के लिए सहमत होना होगा।
C ++ 11 में कोई पोर्टेबल तरीका नहीं है (जो मुझे पता है) बहु-धागा कार्यक्रम में गैर-सहकारी रूप से एक धागे को मारने (यानी सभी थ्रेड्स को मारे बिना)। ऐसी सुविधा को डिजाइन करने के लिए कोई प्रेरणा नहीं थी।
एक std::thread
इस सदस्य कार्य हो सकता है:
native_handle_type native_handle();
आप ओएस-निर्भर फ़ंक्शन को कॉल करने के लिए इसका उपयोग करने में सक्षम हो सकते हैं जो आप चाहते हैं। उदाहरण के लिए ऐप्पल के ओएस पर, यह फ़ंक्शन मौजूद है और native_handle_type
ए pthread_t
। यदि आप सफल हैं, तो आप संसाधनों को लीक करने की संभावना रखते हैं।
std::terminate
न तो स्थैतिक विध्वंसक कहता है और न ही यह आउटपुट बफ़र्स को फ्लश करता है, इसलिए जिस क्रम में संसाधन जारी किए जाते हैं वह अच्छी तरह से परिभाषित नहीं होता है, और न ही आपके पास कोई गारंटी है कि आपका कोई डेटा उपयोगकर्ता को दिखाई देता है या स्थायी स्टोर को लिखा है, या यहां तक कि सुसंगत और पूर्ण।
exit()
या abort()
एक ही समग्र प्रभाव के लिए भी कर सकते हैं ।
@ हावर्ड हिनांत का जवाब सही और व्यापक दोनों है । लेकिन यह गलत समझा जा सकता है अगर यह बहुत जल्दी पढ़ा है, क्योंकिstd::terminate()
(पूरी प्रक्रिया) "टर्मिनेटिंग" के समान नाम होता है जो @AlexanderVX के दिमाग में था (1 धागा)।
सारांश: "1 धागा + बलपूर्वक समाप्त करें (लक्ष्य धागा सहयोग नहीं करता है) + शुद्ध C ++ 11 = कोई रास्ता नहीं है।"
std::terminate()
जवाब क्लासिक शरारती जिनी कहानी जैसा है; यह ओपी की चिट्ठी की इच्छा को पूरा करता है, हालांकि वह उस तरह से नहीं था जैसा वह चाहता था । समझदार हास्य ने मुझे मुस्कुरा दिया। :-)
इस प्रश्न में वास्तव में अधिक गहरी प्रकृति है और सामान्य रूप से मल्टीथ्रेडिंग अवधारणाओं की अच्छी समझ आपको इस विषय के बारे में जानकारी प्रदान करेगी। वास्तव में कोई भी भाषा या कोई भी ऑपरेटिंग सिस्टम नहीं है जो आपको उपयोग न करने की चेतावनी के बिना अतुल्यकालिक अचानक धागा समाप्ति के लिए सुविधाएं प्रदान करता है। और ये सभी निष्पादन वातावरण डेवलपर को दृढ़ता से सलाह देते हैं या यहां तक कि सहकारी या तुल्यकालिक थ्रेड समाप्ति के आधार पर मल्टीथ्रेडिंग एप्लिकेशन बनाने की आवश्यकता होती है। इस सामान्य निर्णय और सलाह का कारण यह है कि वे सभी एक ही सामान्य मल्टीथ्रेडिंग मॉडल के आधार पर बनाए गए हैं।
आइए दूसरे के फायदे और सीमाओं को बेहतर ढंग से समझने के लिए मल्टीप्रोसेसिंग और मल्टीथ्रेडिंग अवधारणाओं की तुलना करें।
मल्टीप्रोसेसिंग पूरे निष्पादन वातावरण के विभाजन को ऑपरेटिंग सिस्टम द्वारा नियंत्रित पूरी तरह से पृथक प्रक्रियाओं के सेट में विभाजित करता है। प्रक्रिया शामिल है और निष्पादन पर्यावरण राज्य को अलग करती है जिसमें प्रक्रिया की स्थानीय मेमोरी और उसके अंदर डेटा और सभी सिस्टम संसाधन जैसे फ़ाइल, सॉकेट, सिंक्रनाइज़ेशन ऑब्जेक्ट शामिल हैं। अलगाव प्रक्रिया की एक महत्वपूर्ण रूप से महत्वपूर्ण विशेषता है, क्योंकि यह प्रक्रिया सीमाओं द्वारा दोष प्रसार को सीमित करता है। दूसरे शब्दों में, कोई भी प्रक्रिया प्रणाली में किसी अन्य प्रक्रिया की स्थिरता को प्रभावित नहीं कर सकती है। प्रक्रिया व्यवहार के लिए भी यही सच है लेकिन कम प्रतिबंधित और अधिक धुंधले तरीके से। ऐसे वातावरण में किसी भी प्रक्रिया को किसी भी "मनमाने" क्षण में मारा जा सकता है, क्योंकि सबसे पहले प्रत्येक प्रक्रिया को अलग किया जाता है, दूसरे,
इसके विपरीत, मल्टीथ्रेडिंग एक ही प्रक्रिया में कई थ्रेड्स चलाता है। लेकिन यह सभी धागे एक ही अलगाव बॉक्स हैं और प्रक्रिया की आंतरिक स्थिति का कोई भी ऑपरेटिंग सिस्टम नियंत्रण नहीं है। परिणामस्वरूप कोई भी धागा वैश्विक प्रक्रिया स्थिति को बदलने में सक्षम है और साथ ही इसे भ्रष्ट भी करता है। उसी क्षण जिन बिंदुओं में थ्रेड की स्थिति को अच्छी तरह से जाना जाता है एक थ्रेड को मारने के लिए सुरक्षित रूप से पूरी तरह से आवेदन तर्क पर निर्भर करता है और न तो ऑपरेटिंग सिस्टम के लिए और न ही प्रोग्रामिंग भाषा रनटाइम के लिए जाना जाता है। परिणामस्वरूप मनमाने ढंग से थ्रेड समाप्ति का अर्थ है कि इसे अपने निष्पादन पथ के मनमाने बिंदु पर मारना और आसानी से प्रक्रिया-व्यापी डेटा भ्रष्टाचार, मेमोरी और लीकेज को संभालना,
इसके कारण सामान्य दृष्टिकोण डेवलपर्स को सिंक्रोनस या सहकारी थ्रेड समाप्ति को लागू करने के लिए मजबूर करना है, जहां एक धागा अन्य थ्रेड समाप्ति और अन्य थ्रेड को अच्छी तरह से परिभाषित बिंदु में अनुरोध कर सकता है, इस अनुरोध की जांच कर सकता है और अच्छी तरह से परिभाषित राज्य से शटडाउन प्रक्रिया शुरू कर सकता है। सुरक्षित और सुसंगत तरीके से सभी वैश्विक प्रणाली-व्यापी संसाधनों और स्थानीय प्रक्रिया-व्यापी संसाधनों को जारी करने के साथ।
C ++ थ्रेड को समाप्त करने के लिए OS पर निर्भर फ़ंक्शन का उपयोग करने की युक्तियां:
std::thread::native_handle()
केवल कॉल करने से पहले थ्रेड के मान्य देशी हैंडल प्रकार प्राप्त कर सकते हैं join()
या detach()
। उसके बाद, native_handle()
0 रिटर्न - pthread_cancel()
coredump होगा।
प्रभावी रूप से देशी थ्रेड समाप्ति फ़ंक्शन (जैसे pthread_cancel()
) को कॉल करने के लिए , आपको कॉल करने से पहले देशी हैंडल को सहेजने की आवश्यकता है std::thread::join()
या std::thread::detach()
। ताकि आपके मूल टर्मिनेटर के पास हमेशा उपयोग के लिए एक वैध देशी हैंडल हो।
अधिक स्पष्टीकरण कृपया देखें: http://bo-yang.github.io/2017/11/19/cpp-kill-detached-thread ।
मुझे लगता है कि जिस धागे को मारने की जरूरत है, वह या तो किसी भी तरह के वेटिंग मोड में है, या कोई भारी काम कर रहा है। मैं एक "भोले" तरीके का उपयोग करने का सुझाव दूंगा।
कुछ वैश्विक बूलियन को परिभाषित करें:
std::atomic_bool stop_thread_1 = false;
निम्नलिखित कोड (या समान) को कई प्रमुख बिंदुओं में रखें, इस तरह से यह कॉल स्टैक में सभी कार्यों का कारण बनेगा जब तक कि धागा स्वाभाविक रूप से समाप्त न हो जाए:
if (stop_thread_1)
return;
फिर धागे को दूसरे (मुख्य) धागे से रोकने के लिए:
stop_thread_1 = true;
thread1.join ();
stop_thread_1 = false; //(for next time. this can be when starting the thread instead)