2011-09-30 11 views
19

स्थानीय स्थिर चर (जो फ़ंक्शन कॉल के बीच अपना मान रखता है) को परिभाषित करने के लिए कैसे अलग-अलग धागे के बीच साझा नहीं किया जाता है?थ्रेड-स्थानीय स्थानीय स्थैतिक चर को परिभाषित करने के लिए कैसे?

मैं दोनों सी में और सी ++

+0

आप किस ओएस का उपयोग कर रहे हैं? टीएलएस यूनिक्स और विंडोज़ के बीच पोर्टेबल नहीं है। – bdonlan

+3

सी ++ 11 [i thread_local'] (http://en.cppreference.com/w/cpp/language/storage_duration) नामक एक और संग्रहण अवधि प्रस्तुत करता है। इसका उपयोग करने का प्रयास करें। – Nawaz

+0

ओएस विंडोज़ है ... –

उत्तर

9

Windows का उपयोग कर Windows API पर: TlsAlloc()/TlsSetValue()/TlsGetValue()

विंडोज पर

संकलक आंतरिक का उपयोग कर: लिनक्स (अन्य POSIX पर उपयोग _declspec(thread)

? ??): get_thread_area() और संबंधित

+0

, टीएलएस फ़ंक्शंस वही हैं जो मैं ढूंढ रहा था। –

+2

आप टीएलएसफ़्री भूल गए :-) –

2

वर्तमान सी मानक धागे या दोनों के लिए ही कोई मॉडल है एक जवाब के लिए देख रहा हूँ, ताकि आप एक जवाब है, वहाँ नहीं मिल सकता है।

उस के लिए पॉज़िक्स द्वारा उपयोग की जाने वाली उपयोगिता pthread_[gs]etspecific है।

सी मानक का अगला संस्करण थ्रेड जोड़ता है और थ्रेड स्थानीय संग्रहण की अवधारणा है।

-3

आप प्रत्येक थ्रेड के लिए ढेर से आवंटित डेटा संरचना बना सकते हैं।

उदाहरण:

struct ThreadLocal 
{ 
    int var1; 
    float var2; 
    //etc.. 
} 
8

बस अपने फ़ंक्शन में स्थिर और __thread का उपयोग करें।

उदाहरण:

int test(void) 
{ 
     static __thread a; 

     return a++; 
} 
+3

__thread मानक है? –

+2

@Ali: नहीं, यह जीसीसी और कुछ अन्य कंपाइलर्स द्वारा प्रदान किया गया एक विस्तार है। एमएसवीसी पर, मुझे लगता है कि आप इसके बजाय '__declspec (थ्रेड)' का उपयोग करते हैं। –

+3

__thread linux, bsd, aix, और xl_c, gcc, और कई अन्य कंपाइलर्स के साथ काम करता है। इसे विंडोज़ पर __declspec (थ्रेड) के लिए छोटा रूप से परिभाषित किया जा सकता है। –

1

आप प्रति थ्रेड ID सिंगलटन के रूप में अपने स्वयं के धागे विशिष्ट स्थानीय भंडारण कर सकते हैं। कुछ ऐसा:

struct ThreadLocalStorage 
{ 
    ThreadLocalStorage() 
    { 
     // initialization here 
    } 
    int my_static_variable_1; 
    // more variables 
}; 

class StorageManager 
{ 
    std::map<int, ThreadLocalStorage *> m_storages; 

    ~StorageManager() 
    { // storage cleanup 
     std::map<int, ThreadLocalStorage *>::iterator it; 
     for(it = m_storages.begin(); it != m_storages.end(); ++it) 
      delete it->second; 
    } 

    ThreadLocalStorage * getStorage() 
    { 
     int thread_id = GetThreadId(); 
     if(m_storages.find(thread_id) == m_storages.end()) 
     { 
      m_storages[thread_id] = new ThreadLocalStorage; 
     } 

     return m_storages[thread_id]; 
    } 

public: 
    static ThreadLocalStorage * threadLocalStorage() 
    { 
     static StorageManager instance; 
     return instance.getStorage(); 
    } 
}; 

GetThreadId(); कॉलर की थ्रेड आईडी निर्धारित करने के लिए एक मंच विशिष्ट कार्य है। कुछ इस तरह:

void threadFunction(void*) 
{ 
    StorageManager::threadLocalStorage()->my_static_variable_1 = 5; //every thread will have 
                  // his own instance of local storage. 
} 
+0

आपको कई थ्रेड्स द्वारा एक्सेस से 'm_storages' की सुरक्षा के लिए सिंक्रनाइज़ेशन (जैसे पढ़ना/लिखना म्यूटेक्स) की भी आवश्यकता होगी। बेशक –

+0

। तुम सही हो। – GreenScape

+0

न केवल m_storages, बल्कि std :: मानचित्र और स्थानीय रूप से "स्थैतिक संग्रहण प्रबंधक उदाहरण;" धागा सुरक्षित नहीं है। देशी कोड में एक उच्च दक्षता सिंगलटन लागू करना एक आसान काम नहीं है, स्कॉट मेयर्स और आंद्रेई अलेक्जेंड्रेस्कू द्वारा "सी ++ और डबल-चेक किए गए लॉकिंग के खतरे" देखें। http://erdani.com/publications/DDJ_Jul_Aug_2004_revised.pdf – zhaorufei

2

तुम भी सी ++ 11 धागा स्थानीय भंडारण संयोजनों का उपयोग कर सकते हैं सेल्सियस तक पहुँच है या नहीं:

int GetThreadId() 
{ 
    int id; 
#ifdef linux 
    id = (int)gettid(); 
#else // windows 
    id = (int)GetCurrentThreadId(); 
#endif 
    return id; 
} 

अब, एक धागा समारोह के भीतर आप इसका इस्तेमाल कर सकते हैं स्थानीय भंडारण है ++ 11।

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