जब आप एक चर घोषित करते हैं thread_local
तो प्रत्येक थ्रेड की अपनी प्रति होती है। जब आप इसे नाम से संदर्भित करते हैं, तो वर्तमान थ्रेड से जुड़ी प्रतिलिपि का उपयोग किया जाता है। जैसे
thread_local int i=0;
void f(int newval){
i=newval;
}
void g(){
std::cout<<i;
}
void threadfunc(int id){
f(id);
++i;
g();
}
int main(){
i=9;
std::thread t1(threadfunc,1);
std::thread t2(threadfunc,2);
std::thread t3(threadfunc,3);
t1.join();
t2.join();
t3.join();
std::cout<<i<<std::endl;
}
यह कोड "2349", "3249", "4239", "4329", "2439" या "3429" को आउटपुट करेगा, लेकिन कभी कुछ और नहीं। प्रत्येक थ्रेड की अपनी प्रति है i
, जिसे असाइन किया गया है, इंक्रीमेंट किया गया है और फिर प्रिंट किया गया है। चल रहे धागे main
की अपनी एक प्रति भी होती है, जिसे शुरुआत में सौंपा जाता है और फिर अपरिवर्तित छोड़ दिया जाता है। ये प्रतियां पूरी तरह से स्वतंत्र हैं, और प्रत्येक का एक अलग पता है।
यह केवल वह नाम है जो उस संबंध में विशेष है --- यदि आप एक thread_local
चर का पता लेते हैं तो आपके पास बस एक सामान्य सूचक है जो एक सामान्य वस्तु है, जिसे आप स्वतंत्र रूप से थ्रेड्स के बीच पारित कर सकते हैं। जैसे
thread_local int i=0;
void thread_func(int*p){
*p=42;
}
int main(){
i=9;
std::thread t(thread_func,&i);
t.join();
std::cout<<i<<std::endl;
}
चूंकि पता i
थ्रेड फ़ंक्शन को दिया जाता है, तो i
मुख्य थ्रेड से संबंधित की प्रतिलिपि को असाइन किया जा सकता है, भले ही वह हो thread_local
। यह कार्यक्रम इस प्रकार "42" आउटपुट देगा। यदि आप ऐसा करते हैं, तो आपको यह ध्यान रखने की आवश्यकता है कि *p
धागे के बाहर निकलने के बाद एक्सेस नहीं किया गया है, अन्यथा आपको किसी भी अन्य मामले की तरह एक लटकन सूचक और अपरिभाषित व्यवहार मिलता है, जहां इंगित की गई वस्तु नष्ट हो जाती है।
thread_local
चर को "पहले उपयोग से पहले" आरंभ किया जाता है, इसलिए यदि उन्हें किसी दिए गए धागे से कभी नहीं छुआ जाता है, तो जरूरी नहीं कि वे कभी भी प्रारंभिक हों। यह thread_local
प्रोग्रामर को प्रोग्राम के हर वैरिएबल के निर्माण से बचने के लिए एक थ्रेड के लिए अनुमति देता है जो पूरी तरह से स्व-निहित है और उनमें से किसी को भी नहीं छूता है। जैसे
struct my_class{
my_class(){
std::cout<<"hello";
}
~my_class(){
std::cout<<"goodbye";
}
};
void f(){
thread_local my_class unused;
}
void do_nothing(){}
int main(){
std::thread t1(do_nothing);
t1.join();
}
इस कार्यक्रम में 2 धागे हैं: मुख्य धागा और मैन्युअल रूप से निर्मित धागा। न तो थ्रेड कॉल होता है f
, इसलिए thread_local
ऑब्जेक्ट का उपयोग कभी नहीं किया जाता है। इसलिए यह अनिर्दिष्ट है कि क्या कंपाइलर 0, 1 या 2 इंस्टेंसेस का निर्माण करेगा my_class
, और आउटपुट "", "हेल्लोहेलोग्लूडबाईगूडबाई" या "हेल्लोगूडबाई" हो सकता है।
strtok
।strtok
एक भी पिरोया वातावरण में भी टूट गया है।