2010-09-29 12 views
17

मैं कई बच्चे धागे बनाने के लिए pthread_create का उपयोग करता हूं। एक समय में, मुख्य धागा सभी बाल धागे को मारना चाहता है या सेगमेंट फालट होगा। इसे पूरा करने के लिए मुझे किस फ़ंक्शन का उपयोग करना चाहिए? मैंने Google से जवाब खोजा और pthread_kill जैसे फ़ंक्शन प्राप्त कर लिया। लेकिन मुझे नहीं पता था कि मुझे बच्चों को मारने के लिए मुझे किस सिग्नल को भेजना चाहिए। मेरा चल रहा वातावरण आरएचईएल 5.4 है और प्रोग्रामिंग भाषा सीपाथ्रेड के लिए, मुख्य धागे से बाल धागे को कैसे मारें

+2

वाह, सभी धागे को मार दें क्योंकि एक सीगफॉल्ट होगा? क्या तुम मजाक कर रहे हो? मैं कभी ऐसा कोड नहीं लेता जो उस तरह से संभाला जाता है। –

+1

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

+2

तर्क को ठीक करें। यदि अन्य धागे अभी भी उपयोगी काम कर रहे हैं, तो आप प्रोग्राम को समाप्त करने की कोशिश क्यों कर रहे हैं? यदि अन्य धागे को अभी भी इन वस्तुओं की आवश्यकता होती है, तब भी जब 'मुख्य' गुंजाइश से बाहर हो जाता है, तो उन्हें 'मुख्य स्टैक' पर आवंटित क्यों किया जाता है? –

उत्तर

20

pthread_cancel का उपयोग करके धागे को "रद्द" करना संभव है। हालांकि, यह आमतौर पर सबसे अच्छा अभ्यास नहीं है हालांकि एक सेगफाल्ट जैसी चरम परिस्थितियों में इसे उचित दृष्टिकोण माना जा सकता है।

+1

इस यूआरएल में एक उदाहरण है http://linux.die.net/man/3/pthread_cleanup_push – enthusiasticgeek

+4

'pthread_cancel' को सर्वोत्तम अभ्यास क्यों नहीं माना जाता है? और यदि यह सबसे अच्छा अभ्यास नहीं है, तो क्या है? – darnir

6

आप अपने धागे से प्रत्येक के लिए SIG_TERM भेजना चाहिए,

int pthread_kill(pthread_t thread, int sig); 

एक त्वरित तरीका सभी धागे से छुटकारा पाने के का उपयोग कर (मुख्य अलावा) कांटा() और बच्चे के साथ जा रहा रखने के लिए है।
नहीं अति स्वच्छ ...

if (fork()) exit(0); // deals also with -1... 
24

सामान्य तौर पर, आप नहीं है वास्तव में हिंसक एक बच्चे धागा को मारने के लिए चाहते हैं, लेकिन इसके बजाय आप इसे पूछने के लिए समाप्त करने के लिए चाहते हैं। इस तरह आप यह सुनिश्चित कर सकते हैं कि बच्चा एक सुरक्षित स्थान पर छोड़ रहा है और उसके सभी संसाधन साफ ​​हो गए हैं।

मैं आम तौर पर माता-पिता और बच्चे के बीच साझा राज्य के एक छोटे टुकड़े के साथ ऐसा करता हूं ताकि माता-पिता को प्रत्येक बच्चे को "अनुरोध छोड़ने" को संवाद करने की अनुमति मिल सके। यह सिर्फ एक म्यूटेक्स द्वारा संरक्षित प्रत्येक बच्चे के लिए एक बुलियन मूल्य हो सकता है। बच्चा समय-समय पर इस मूल्य की जांच करता है (प्रत्येक लूप पुनरावृत्ति, या आपके बच्चे के धागे में जो भी सुविधाजनक चेकपॉइंट है)। "Quit_request" सत्य होने पर, बच्चे का धागा साफ़ हो जाता है और pthread_exit पर कॉल करता है।

acquire shared mutex 
set quit_request to true 
pthread_join the child 

pthread_join कुछ समय लग सकता है, पर बार-बार कैसे बच्चे अपने अनुरोध छोड़ने की जाँच करता है निर्भर करता है:

माता-पिता की तरफ, "kill_child" नियमित कुछ इस तरह लग रहा है। सुनिश्चित करें कि आपका डिज़ाइन देरी हो सकती है जो भी हो सकता है।

+0

धागे के बीच साझा की गई किसी भी स्मृति को संशोधित करने से पहले एक म्यूटेक्स प्राप्त करने के लिए आम तौर पर अच्छा अभ्यास होता है, तथ्य यह है कि यह एक ही ध्वज है जो गैर-शून्य (या झूठी) स्थिति के लिए चेक किया जा रहा है, इसका मतलब है कि आपको वास्तव में आवश्यकता नहीं है एक म्यूटक्स पकड़ने के लिए। इस मामले में, वास्तव में बहुत कुछ नहीं है जो डेटा कोरेन्सी परिप्रेक्ष्य से गलत हो सकता है। –

+2

@ ब्रेंट: [यह प्रश्न] (http://stackoverflow.com/questions/21183261/is-a-race-condition-possible-when-only-one-thread-writes-to-a-bool-variable-in -सी) एक उदाहरण दिखाता है जहां एक बार लिखा गया एक झंडा भी जटिल अनुकूलन के बाद दौड़ की स्थिति का कारण बन सकता है। – dshepherd

+0

सुंदर, यह अद्भुत काम करता है। – djthoms

2

आप पूरे कार्यक्रम के लिए वैश्विक चर का उपयोग कर सकते हैं।

int _fCloseThreads;

जब आप थ्रेड निष्पादन छोड़ना चाहते हैं तो इसे 1 पर सेट करें। धागे को अपने "लूप" में उस चर को जांचें और इसे 1 पर सेट होने पर अच्छी तरह से छोड़ दें। इसे म्यूटेक्स से बचाने की आवश्यकता नहीं है।

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

अंत में, आप pthread_cleanup_push और पॉप चेकआउट कर सकते हैं। वे थ्रेड को अपने कोड में कहीं भी रद्द करने की अनुमति देने के लिए एक मॉडल हैं (एक लांगजंप का उपयोग करते हैं) और फिर थ्रेडप्रोक से बाहर निकलने से पहले अंतिम क्लीनअप फ़ंक्शन को कॉल करें। आप मूल रूप से नीचे अपने थ्रेडप्रोक और क्लीनअप_पॉप के शीर्ष पर cleanup_push डालते हैं, एक अनचाहे फ़ंक्शन बनाते हैं, और उसके बाद कुछ रद्द करने के बिंदुओं पर pthread_cancel() को कॉल द्वारा रद्द किया गया थ्रेड थ्रेडप्रोक पर वापस लॉन्ज करेगा और अनचाहे फ़ंक्शन को कॉल करेगा।

+1

http://linux.die.net/man/3/pthread_cleanup_push का एक उदाहरण है। – enthusiasticgeek

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