2011-12-12 7 views
8

के कारण सेगमेंटेशन गलती मुझे बताती है कि pthread_kill मेरे प्रोग्राम में सेगमेंटेशन गलती का कारण बन रहा है। मूल रूप से मैं pthread_kill का उपयोग कर यह जांचने के लिए उपयोग कर रहा हूं कि कोई धागा जीवित है या नहीं, इसकी आईडी दी गई है।pthread_kill

मैं वेब खोज रहा हूं और पाया कि यह हो सकता है कि pthread_kill टीआईडी ​​अमान्य होने पर सेगमेंटेशन गलती हो रही है। हां, मैंप्रकार के टीआईडी ​​"अमान्य" (मेरे द्वारा प्रदूषित) का उपयोग कर अपने कार्यक्रम का परीक्षण कर रहा हूं। क्या यह वास्तविक कारण हो सकता है?

+0

से पहले अशक्त के लिए जाँच कर रहा है आप किस "अवैध" मान का उपयोग कर रहे हैं? –

+0

@DanFego उदाहरण के लिए, 1001 –

+0

चूंकि pthread_t एक अपारदर्शी प्रकार है, एक पूर्णांक (1001 की तरह) का उपयोग सैद्धांतिक रूप से समस्याओं और बाद में दुर्घटना का कारण बन सकता है। क्या आपको कोई चेतावनी मिलती है -क्या? –

उत्तर

14

pthread_t कोई थ्रेड आईडी नहीं है, या एक संख्यात्मक सूचकांक नहीं है। यह एक अपारदर्शी प्रकार है। मूल्य बनाना परिणामस्वरूप दुर्घटना हो सकती है।

लिनक्स NPTL पर, pthread_t सूचक के रूप में प्रयोग किया जाता है:

int 
__pthread_kill (threadid, signo) 
    pthread_t threadid; 
    int signo; 
{ 
    struct pthread *pd = (struct pthread *) threadid; 

यह काफी स्पष्ट किया जाना चाहिए जहां कोई बात बिगड़ पहले से ही जा रहे हैं :) ध्यान दें कि यह pointerness भी एक कार्यान्वयन विस्तार है - पुराने LinuxThreads कार्यान्वयन के लिए इस्तेमाल किया एक तालिका में संख्यात्मक सूचकांक, और वहां आप वास्तव में टीआईडी ​​बना सकते हैं और चीजों को दुर्घटनाग्रस्त होने की उम्मीद नहीं करते हैं।

आपको थ्रेड जीवन और मृत्यु को ट्रैक करने की आवश्यकता है। pthread_t मान्य है जब तक कि आप इसे सफलतापूर्वक pthread_join पर कॉल न करें। यदि आप यह जांचना चाहते हैं कि मान्यpthread_t जीवित है, तो pthread_tryjoin_np पर कॉल करें; अगर यह EBUSY देता है, तो धागा जीवित है। यदि फ़ंक्शन सफल होता है, pthread_t अब मान्य नहीं है; आपको इस बिंदु पर इसका पुन: उपयोग नहीं करना चाहिए - इसलिए आपको कहीं भी एक नोट बनाना होगा कि वह धागा अब मर चुका है, और अब इसे जांचने की आवश्यकता नहीं है!

आप निश्चित रूप से अपने स्वयं के ट्रैकिंग सिस्टम को कार्यान्वित कर सकते हैं - कहीं भी एक टेबल बना सकते हैं, टीआईडी ​​को सौंपने के लिए एक प्रणाली बना सकते हैं, और उन्हें नए बनाए गए धागे में भेज सकते हैं। बाहर निकलने से पहले प्रत्येक थ्रेड को मृत के रूप में चिह्नित करें (शायद pthread_cleanup_push का उपयोग करके आप थ्रेड रद्दीकरण और pthread_exit) को संभालते हैं, और थ्रेड को अलग करते हैं ताकि आपको इसमें शामिल होने की आवश्यकता न हो (pthread_detach का उपयोग कर)। अब आपके थ्रेड-डेथ रिपोर्टिंग का स्पष्ट नियंत्रण है।

+1

[pthread_kill] के लिए मैन पेज (https://www.kernel.org/doc/man-pages /online/pages/man3/pthread_kill.3.html) कहता है कि आप 'pthread_kill (t, 0)' to 't' के अस्तित्व की जांच 'करने के लिए उपयोग कर सकते हैं, जिसका अर्थ है अमान्य pthread_t मानों के साथ कॉल करने में सक्षम होना। क्या आदमी है पृष्ठ गलत है? – Brandon

+1

@ ब्रैंडन http://sourceware.org/bugzilla/show_bug.cgi?id=4509 और http://udrepper.livejournal.com/16844.html देखें।dreppers तर्क बहुत बौद्धिक आलसी लगता है, लेकिन ऐसा लगता है कि glibc में अमान्य टीआईडी ​​पर pthread_kill का समर्थन करने का कोई इरादा नहीं है, इसलिए थ्रेड के अस्तित्व के लिए परीक्षण करने के लिए pthread_kill का उपयोग करने का दृष्टिकोण कोई काम नहीं है –

+0

@JoshuaClayton लिंक के लिए धन्यवाद। – Brandon

1

मेरी कोड में इस सीमा के आसपास पाने के लिए, मैं शून्य करने के लिए टीआईडी ​​सेट जब कोड

memset(&thread, '\0', sizeof(pthread_t)); 

... नहीं चल रहा है और pthread_kill बुला

//this code will run if thread is not valid 
if (!thread || ESRCH == pthread_kill(thread, 0)) { 
    //do stuff and create the thread 
}