2012-07-18 4 views
5

के विकल्प के लिए मैं pthread_timedjoin_np पर निर्भरता से छुटकारा पाने के तरीके को समझने की कोशिश कर रहा हूं क्योंकि मैं ओएसएक्स पर कुछ कोड बनाने की कोशिश कर रहा हूं।pthread_timedjoin_np

अभी मेरे पास धागे की एक कतार है जो मैं पॉपिंग कर रहा हूं, उस pthread_timedjoin_np कर रहा हूं और यदि वे वापस नहीं आते हैं, तो वे कतार पर वापस धकेल जाते हैं।

प्रत्येक थ्रेड के लिए बुलाए गए थ्रेड_फंक्शन का अंत pthread_exit (0) करता है; ताकि प्राप्त करने वाला धागा शून्य के वापसी मूल्य की जांच कर सके।

मैंने सोचा कि मैं एक समान प्रभाव प्राप्त करने के लिए pthread_cond_timedwait() का उपयोग करने का प्रयास कर सकता हूं, हालांकि मुझे लगता है कि मुझे एक कदम याद आ रहा है।

मैंने सोचा कि मैं एक म्यूटेक्स के भीतर कार्यकर्ता थ्रेड को एक सिग्नल और pthread_exit() सिग्नल बनाने में सक्षम होगा, और कार्यकर्ता थ्रेड बी सिग्नल पर जाग सकता है, और फिर pthread_join()। समस्या यह है कि, थ्रेड बी नहीं जानता कि कौन सा धागा सशर्त सिग्नल फेंक दिया। क्या मुझे स्पष्ट रूप से संवैधानिक सिग्नल के हिस्से के रूप में या क्या करना है?

धन्यवाद

डेरेक

+0

डुप्लिकेट नहीं है, लेकिन कुछ उत्तर सहायक हो सकता है: http: // stackoverflow।कॉम/प्रश्न/73468/गैर-अवरुद्ध-pthread- शामिल हों – Corbin

उत्तर

1

निर्माता-उपभोक्ता कतार। थ्रेड कतार * स्वयं, और इसलिए उनके परिणाम, (यदि कोई हैं), बाहर निकलने से पहले कतार में। कतार पर प्रतीक्षा करें।

कोई मतदान नहीं, कोई विलंबता नहीं।

अपने वर्तमान डिज़ाइन के साथ, आपको() लौटा हुआ धागा वैल्यूप्टर प्राप्त करने और यह सुनिश्चित करने के लिए होगा कि वे नष्ट हो जाएं।

हो सकता है कि आप कभी-कभी असली थ्रेडपूल पर जा सकें, जहां कार्य आइटम धागे के लिए कतारबद्ध होते हैं जो कभी समाप्त नहीं होते हैं, (इसलिए थ्रेड को समाप्त/समाप्त/ओवरहेड नष्ट कर दें)?

+0

पुन: असली थ्रेडपूल..इसके पास पहले यह विचार था। मैं क्यूटी फ्रेमवर्क में काम कर रहा हूं और मैंने पहले अपने पूल/भविष्य मॉडल का उपयोग किया है, लेकिन मुझे यकीन नहीं है कि क्या मैं इस कोड की पोर्टेबिलिटी के नाम पर इसका उपयोग करने में सक्षम हूं – Derek

+0

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

4

यहाँ pthread_timedjoin_np की एक पोर्टेबल कार्यान्वयन है। यह थोड़ा महंगा है, लेकिन यह एक पूर्ण ड्रॉप-में प्रतिस्थापन है:

struct args { 
    int joined; 
    pthread_t td; 
    pthread_mutex_t mtx; 
    pthread_cond_t cond; 
    void **res; 
}; 

static void *waiter(void *ap) 
{ 
    struct args *args = ap; 
    pthread_join(args->td, args->res); 
    pthread_mutex_lock(&args->mtx); 
    args->joined = 1; 
    pthread_mutex_unlock(&args->mtx); 
    pthread_cond_signal(&args->cond); 
    return 0; 
} 

int pthread_timedjoin_np(pthread_t td, void **res, struct timespec *ts) 
{ 
    pthread_t tmp; 
    int ret; 
    struct args args = { .td = td, .res = res }; 

    pthread_mutex_init(&args.mtx, 0); 
    pthread_cond_init(&args.cond, 0); 
    pthread_mutex_lock(&args.mtx); 

    ret = pthread_create(&tmp, 0, waiter, &args); 
    if (ret) goto done; 

    do ret = pthread_cond_timedwait(&args.cond, &args.mtx, ts); 
    while (!args.joined && ret != ETIMEDOUT); 

    pthread_mutex_unlock(&args.mtx); 

    pthread_cancel(tmp); 
    pthread_join(tmp, 0); 

    pthread_cond_destroy(&args.cond); 
    pthread_mutex_destroy(&args.mtx); 

    return args.joined ? 0 : ret; 
} 

के बाद से मैं मौके पर यह लिखा है और यह परीक्षण नहीं किया छोटी त्रुटियों हो सकता है, लेकिन अवधारणा आवाज़ है।

+0

पोस्ट करने से पहले मैं वास्तव में मार्टिन्स की तरह एक योजना के साथ आया था, अगर ऐसा लगता है कि यह अच्छी तरह से काम नहीं कर रहा है तो मैं इसे आज़मा दूंगा। – Derek

+0

मार्टिन का समाधान अपर्याप्त ओवरहेड नहीं होने और अवधारणात्मक रूप से बेहतर होने के दृष्टिकोण से क्लीनर है। मेरा गैर-पोर्टेबल फ़ंक्शन के लिए केवल एक ड्रॉप-इन प्रतिस्थापन है जो आपको बिना किसी रीडिज़ाइन किए गैर-पोर्टेबल कोड को ठीक करने की अनुमति देता है। –

0

alarm के साथ समाधान।

pthread को रद्द करने में सक्षम होना चाहिए, इसलिए यह बाहरी द्वारा रोक सकता है। (pthread_timedjoin_np के साथ भी)।

pthread_timedjoin_np प्रतीक्षा समय के बाद ETIMEOUT के साथ वापसी।

  1. alarm सेट करें, alarm का उपयोग करें "TIMEOUT" संकेत भी दे सकता है।
  2. हैंडलर में, बस pthread_cancel यह। (केवल टाइमआउट इसे चलाएं)।
  3. pthread_join यह मुख्य धागे में है।
  4. रीसेट alarm

मैं यहाँ में परीक्षण कोड लिखने: github