2013-04-22 5 views
5

मैंने पर्थ्रेड टीएलएस का उपयोग करके एक प्रकार का "थ्रेड लोकल सिंगलटन" लागू किया, और मुझे आश्चर्य हुआ कि कैसे (और कब) मैं इस मामले में pthread_key_t को संभवतः हटा सकता हूं, क्योंकि अब यह है कि टीएलएस कुंजी द्वारा उपयोग की जाने वाली मेमोरी कभी नहीं होगी मुक्त किया गया।पर्थ्रेड थ्रेड-लोकल-सिंगलटन, टीएलएस कुंजी कब जारी करें?

इस का उद्देश्य उपयोग एक वर्ग एक ThreadLocalSingleton < से निकाले जाते हैं एक > जो एक एक धागा स्थानीय सिंगलटन बनाता है, यह सोचते हैं कि एक ही निजी निर्माणकर्ता और है ThreadLocalSingleton < एक > ए के मित्र हैं यह बताने के लिए है

ओह और भी - क्या आप उस कार्यान्वयन के साथ कोई समस्या देखते हैं; क्या मैंने कुछ भी महत्वपूर्ण देखा?

#include <pthread.h> 
#include <iostream> 

template <class T> 
class ThreadLocalSingleton 
{ 
private: 
    static pthread_key_t tlsKey; 
    static pthread_once_t tlsKey_once; 

    static void tls_make_key() 
    { 
     (void)pthread_key_create(&ThreadLocalSingleton::tlsKey, ThreadLocalSingleton::tls_destructor); 
    } 

    static void tls_destructor(void* obj) 
    { 
     delete ((T*)obj); 
     pthread_setspecific(tlsKey, NULL); // necessary or it will call the destructor again. 
    } 

public: 

    /* 
    * A thread-local singleton getter, the resulted object must never be released, 
    * it is auto-released when the thread exits. 
    */ 
    static T* getThreadInstance(void) 
    { 
     pthread_once(&tlsKey_once, ThreadLocalSingleton::tls_make_key); 
     T* instance = (T*)pthread_getspecific(tlsKey); 
     if(!instance) 
     { 
      try 
      { 
       instance = new T; 
       pthread_setspecific(tlsKey, instance); 
      } 
      catch (const char* ex) 
      { 
       printf("Exception during thread local singleton init: %s\n",ex); 
      } 
     } 
     return instance; 
    } 
}; 
template <class T> 
pthread_key_t ThreadLocalSingleton<T>::tlsKey; 
template <class T> 
pthread_once_t ThreadLocalSingleton<T>::tlsKey_once = PTHREAD_ONCE_INIT; 
+0

[लिनक्स प्रोग्रामिंग इंटरफेस: एक लिनक्स और यूनिक्स सिस्टम प्रोग्रामिंग हैंडबुक] (http://www.amazon.com/dp/1593272200) में केरिस्क के अनुसार, मुझे विश्वास है कि आप * थ्रेड विशिष्ट डेटा * ('pthread_key_create) का उपयोग कर रहे हैं 'और दोस्तों) बल्कि * थ्रेड स्थानीय संग्रहण * (स्थिर और वैश्विक चर पर' __thread' कीवर्ड)। – jww

उत्तर

2

आपका कार्यान्वयन बहुत ही सुरुचिपूर्ण दिखता है।

Open Group Specification of pthread_key_create के अनुसार, आप नाशक में शून्य के संदर्भ में स्थापित करने के लिए नहीं है:

एक वैकल्पिक नाशक समारोह प्रत्येक कुंजी मान के साथ जुड़ा हो सकता है। थ्रेड निकास पर, यदि किसी कुंजी मान में गैर-नल डिस्ट्रक्टर पॉइंटर होता है, और थ्रेड में उस कुंजी से जुड़े गैर-नल मान होते हैं, तो कुंजी का मान NULL पर सेट होता है, और उसके बाद फ़ंक्शन की ओर इशारा किया जाता है पहले से जुड़े मूल्य को इसके एकमात्र तर्क के रूप में।

मुझे लगता है कि यह भी दर्शाता है कि मुख्य वस्तु स्वयं ही pthread द्वारा autodestroyed किया जाएगा। आपको केवल कुंजी के पीछे संग्रहीत करने का ख्याल रखना होगा, जो ठीक है कि आपका delete ((T*)obj); करता है।

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