2010-11-19 7 views
5

क्या इस कोड का व्यवहार अच्छी तरह से परिभाषित है?क्या यह मुख्य धागे पर pthread_join को कॉल करने के लिए मान्य है?

#include <stdio.h> 
#include <pthread.h> 

pthread_t mt; 

void *start(void *x) 
{ 
    void *y; 
    pthread_join(mt, &y); 
    printf("joined main thread\n"); 
    return 0; 
} 

int main() 
{ 
    pthread_t t; 
    mt = pthread_self(); 
    pthread_create(&t, 0, start, 0); 
    pthread_exit(0); 
} 

उत्तर

7

हां, यह संभव है। दरअसल, यह संभावना मुख्य कारणों में से एक है क्यों pthread_detach() मौजूद है। pthread_detach() के लिए POSIX डॉक्स (man pthread_detach देखें) से:

It has been suggested that a "detach" function is not necessary; the 
    detachstate thread creation attribute is sufficient, since a thread 
    need never be dynamically detached. However, need arises in at least 
    two cases: 

    1. In a cancellation handler for a pthread_join() it is nearly essen- 
     tial to have a pthread_detach() function in order to detach the 
     thread on which pthread_join() was waiting. Without it, it would 
     be necessary to have the handler do another pthread_join() to 
     attempt to detach the thread, which would both delay the cancella- 
     tion processing for an unbounded period and introduce a new call 
     to pthread_join(), which might itself need a cancellation handler. 
     A dynamic detach is nearly essential in this case. 


    2. In order to detach the "initial thread" (as may be desirable in 
     processes that set up server threads). 

तो आप क्या प्रस्तावित नहीं किए हों मानकों के अनुसार ठीक है।

संपादित करें: बस ऐसे ही आगे की पुष्टि के लिए, POSIX description of exec() कहता है:

नई प्रक्रिया छवि में प्रारंभिक धागा, joinable किया जाएगा के रूप में अगर detachstate विशेषता PTHREAD_CREATE_JOINABLE करने के लिए सेट के साथ बनाया।

+0

क्या आप अंतिम संपादन के लिए अपने स्रोत में एक लिंक जोड़ने पर विचार करेंगे? मुझे विश्वास है कि आप इसे यहां से प्राप्त कर चुके हैं: http://pubs.opengroup.org/onlinepubs/009695399/functions/exec.html, लेकिन मैं पहले पुष्टि करना चाहता था। महान जवाब, यद्यपि! – currysensei

+1

@currysensei: जोड़ा गया! – psmears

0

मैं तुम क्यों एक वास्तविक दुनिया आवेदन में यह करना होगा कल्पना नहीं कर सकते (किसी एक उदाहरण टिप्पणी कृपया अगर आप एक के बारे में सोच सकते हैं), लेकिन मैं नहीं मानता कि यह और भी संभव है। मैंने जो पठारों को देखा है, उनके बारे में सभी खोज हमेशा मुख्य धागे से नहीं जुड़ती हैं, न कि द्वितीयक धागे।

जुड़ने के लिए भी आवश्यक है कि आप जो थ्रेड शामिल करने का प्रयास कर रहे हैं वह PTHREAD_CREATE_JOINABLE ध्वज के साथ बनाया गया है। मैं इस बात का कोई दस्तावेज नहीं ढूंढ पाया कि मुख्य धागा इस प्रकार बनाया गया है या नहीं।

कोडेगुरु के पास here पर एक समान प्रश्न है जो इसे साफ़ करने में मदद कर सकता है या नहीं।

क्या आप पूरा करना चाहते हैं बच्चे धागा जारी करने के बाद मुख्य थ्रेड से बाहर निकल गया है, तो आप, बच्चे धागा अलग बना सकते हैं या का उपयोग fork/vfork बजाय, क्या मंच पर निर्भर करता है जिस पर आप हैं चाहिए।

+0

'PTHREAD_CREATE_JOINABLE' POSIX के अनुसार डिफ़ॉल्ट है; इसे प्राप्त करने के लिए आपको 'pthread_attr_t' का उपयोग करने की आवश्यकता नहीं है। –

+0

वैसे, मैं मानता हूं कि यह शायद एक अच्छा अभ्यास नहीं है। मैंने इस सवाल से पूछा कि क्या कार्यान्वयन को इस संदिग्ध उपयोग का समर्थन करना चाहिए, न कि किसी एप्लिकेशन लेखक को इसका उपयोग करना चाहिए या नहीं। :-) –

0

आपका दृष्टिकोण औपचारिक रूप से मेरे लिए वैध लग रहा है, विशेष रूप से जब से तुम main के अंत में pthread_exit कर रहे हैं।

दूसरी ओर मुझे POSIX में कोई संकेत नहीं मिला कि main का आरंभिक धागा शामिल होना चाहिए या नहीं। Psmears के जवाब में तर्क केवल पूछता है कि main अलग-अलग होना चाहिए जहां से इसे शामिल किया जा सके।

इसके अलावा कुछ और दुर्भावनापूर्ण भी pthread_detach को मुख्य या अन्य द्वारा बुलाए गए सबराउटिन से कॉल कर सकता है। तो आपको ऐसे मामले की जांच के लिए निश्चित रूप से pthread_join के वापसी मूल्य की जांच करनी चाहिए।

अपने उदाहरण कोड में इसके अलावा

आप start के सृजन और main की समाप्ति के बीच एक दौड़ है: पहले startpthread_join

पर आता है के लिए उपयोग Mutexing

  • main समाप्त किया जा सकता है mt वैरिएबल को कैप्चर करना चाहिए।

+0

यदि थ्रेड पर 'pthread_detach' पहले ही कॉल किया जा चुका है, तो उस थ्रेड पर' pthread_join' को कॉल करने का परिणाम अपरिभाषित है; इसे किसी भी त्रुटि को वापस करने की आवश्यकता नहीं है, और वास्तव में यह थ्रेड हो सकता है अगर थ्रेड पहले ही समाप्त हो चुका है और इसके संसाधनों को हटा दिया गया है। –

+0

मुख्य धागे को शामिल करने में असमर्थ है, 'start' कॉल' pthread_join' से पहले 'main' कॉल 'pthread_exit'' कोई समस्या नहीं है। एक जुड़ने योग्य धागे के अर्थशास्त्र एक बच्चे की प्रक्रिया के लिए 'पिड' की तरह हैं। जब तक आप इसके लिए प्रतीक्षा न करें और इसकी निकास स्थिति एकत्र न करें, तब तक 'pid' आरक्षित (ज़ोंबी प्रक्रिया) की तरह है,' pthread_t' तब तक वैध है जब तक आप थ्रेड को अलग नहीं करते या शामिल नहीं होते हैं, भले ही यह पहले से बाहर हो गया हो। –

+0

मैं आपकी पहली टिप्पणी से सहमत नहीं हूं। एक गैर-जुड़ने योग्य धागा पता लगाने योग्य है और यह एक अनिर्धारित परिणाम नहीं लेता है। 'Pthread_join() फ़ंक्शन विफल हो जाएगा यदि: * EINVAL * कार्यान्वयन ने पाया है कि थ्रेड द्वारा निर्दिष्ट मान किसी जुड़ने वाले थ्रेड को संदर्भित नहीं करता है। –

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