2011-09-26 19 views
37

C++ 11 नए सूत्रण सामान के ऊपर देख रहे हैं कि कैसे आसानी से यह pthreads को नक्शे को देखने के लिए, मैं thread निर्माता क्षेत्र में उत्सुक खंड नोटिस:सी ++ 11 में, थ्रेड का बिंदु क्या है जो "निष्पादन के धागे का प्रतिनिधित्व नहीं करता"?

धागा();
प्रभाव: एक थ्रेड ऑब्जेक्ट बनाता है जो निष्पादन के धागे का प्रतिनिधित्व नहीं करता है।
Postcondition: get_id() == आईडी()
फेंकता: कुछ भी नहीं।

दूसरे शब्दों में, एक धागा के लिए डिफ़ॉल्ट निर्माता वास्तव में प्रतीत नहीं होता है एक धागा पैदा करते हैं। जाहिर है, यह ऑब्जेक्ट, धागा बनाता है लेकिन इसके लिए कोई बैकिंग कोड नहीं है तो यह कितना उपयोगी है? क्या कोई और तरीका है कि उस वस्तु से "निष्पादन का धागा" संलग्न किया जा सकता है, जैसे thrd.start() या कुछ समान?

+0

सी ++ 11 तुम्हारे और मेरे दोनों को डरा रहा है, सौभाग्य से मैं अब एक कर्नेल देव हूं इसलिए मानकों को अब मुझ पर नहीं बदल रहा है :) –

+5

मुझे लगता है कि उनका मतलब है कि धागा कन्स्ट्रक्टर वास्तविक धागा नहीं बनाता है, यह ऑपरेशन सिस्टम को कॉल नहीं करता है, स्टैक आवंटित नहीं करता है/अन्य संसाधन और आम तौर पर एक बंद धागा नहीं बनाते हैं। मुझे लगता है कि यह जगह पर है इसलिए लोगों को पता चलेगा कि वे इसे शुरू करने से पहले थ्रेड बनाकर कुछ भी बर्बाद नहीं कर रहे हैं (कुछ झंडे भंडारण के अलावा)। – Dani

+5

@ जेसस रामोस: कर्नेल देव मानक परिवर्तन से डरते हैं? अगर मुझे सही याद है कि प्रत्येक नए प्रोसेसर कर्नेल में कुछ तोड़ता है या एक सुविधा जोड़ता है जिसके लिए बहुत सारे पुनर्लेखन को लागू करने की आवश्यकता होती है। – Dani

उत्तर

34

क्या कोई अन्य तरीका है कि उस वस्तु से "निष्पादन का धागा" संलग्न किया जा सकता है, जैसे thrd.start() या कुछ समान है?

// deferred start 
std::thread thread; 

// ... 

// let's start now 
thread = std::thread(functor, arg0, arg1); 

std::thread एक MoveConstructible और MoveAssignable प्रकार है। तो इसका मतलब है कि std::thread zombie(some_functor); std::thread steal(std::move(zombie));zombie जैसे कोड में एक विशेष, लेकिन मान्य, निष्पादन के धागे से जुड़े राज्य में छोड़ा जाएगा। डिफ़ॉल्ट कन्स्ट्रक्टर एक अर्थ में मुक्त आता है क्योंकि इसे केवल उस सटीक स्थिति में रखना है। यह std::thread के सरणी और std::vector<std::thread>::resize जैसे संचालन की अनुमति देता है।

+0

दरअसल ... आपके धागे में 0 की थ्रेड आईडी होगी। कोई आंतरिक मूल धागा संदर्भ नहीं है। यह सरणी और एसटीएल कंटेनर के लिए सिर्फ प्लेसहोल्डर प्रकार है। – Noishe

3

बस अनुमान लगा रहा है, लेकिन इसका मतलब यह है कि धागा शुरू नहीं हुआ है। दूसरे शब्दों में, यह किसी अन्य की तरह एक वस्तु है - इसके पीछे एक वास्तविक ओएस धागा आवश्यक नहीं है। इसे एक और तरीका रखने के लिए, अगर थ्रेड को पर्थ्रेड के शीर्ष पर लागू किया गया था, तो एक सी ++ 11 थ्रेड ऑब्जेक्ट बनाने के लिए आवश्यक रूप से pthread_create() को कॉल नहीं करना चाहिए - केवल थ्रेड शुरू होने पर ही आवश्यकता होती है।

std::vector<int> emptyList; 

emptyList खाली है:

+0

तो, ..., मेरी क्वेरी तब मेरे प्रश्न का दूसरा हिस्सा होगा: "आप इसे कैसे शुरू करते हैं?" – paxdiablo

+0

शायद आप नहीं कर सकते। आखिरकार, यदि आपने शून्य-तर्क कन्स्ट्रक्टर का उपयोग किया है, तो आपने थ्रेड के लिए कुछ भी * * निर्दिष्ट नहीं किया है। ऐसा लगता है कि, मुझे लगता है कि आप इतनी बेकार वस्तु क्यों बना सकते हैं, इस सवाल का कारण बनते हैं। – davmac

+0

इसके बजाय: जैसा कि ल्यूक डैंटन नीचे दिए गए अपने उत्तर में बताते हैं, आप थ्रेड शुरू करने के लिए असाइनमेंट ऑपरेटर का उपयोग कर सकते हैं। – davmac

18

यह इस का वही अर्थ है। एक डिफ़ॉल्ट-निर्मित std::thread की तरह। एक डिफ़ॉल्ट-निर्मित std::ofstream की तरह ही कोई फ़ाइल नहीं खुलती है। कक्षाएं रखने के लिए पूरी तरह से उचित कारण हैं जो डिफ़ॉल्ट रूप से खाली स्थिति में स्वयं को बनाते हैं।


आप एक खाली धागा है:

std::thread myThread; 

आप वास्तव में ऐसा करने से धागा शुरू कर सकते हैं:

myThread = std::thread(f, ...); 

कहाँ f कुछ प्रतिदेय बात है (समारोह सूचक, functor, std::function, आदि), और ... धागे को अग्रेषित करने के लिए तर्क हैं।

8

सिर्फ अनुमान लगा नहीं:

"धागा ऑब्जेक्ट" एक std::thread को दर्शाता है।

"निष्पादन के सूत्र" OS's collection of hardware registers that represent a thread को दर्शाता है।

सी ++ 11 लेकिन आदेश सी ++ बनाने के सभी ओएस भर में पोर्टेबल सूत्रण करने के लिए ओएस धागे के लिए उपयोग के लिए ओएस के एपीआई से अधिक papering कुछ भी नहीं कर रही है।

थ्रेड();
प्रभाव: एक थ्रेड ऑब्जेक्ट बनाता है जो निष्पादन के धागे का प्रतिनिधित्व नहीं करता है।
Postcondition: get_id() == आईडी()
फेंकता: कुछ भी नहीं।

एक डिफ़ॉल्ट std::thread निर्माण निष्पादन की एक धागा है कि ओएस उत्पादन किया गया है का उल्लेख नहीं करता इसका मतलब यह है।

एक std::thread एक नया मान दिया जा सकता है, और इस तरह एक चाल काम बयान से निष्पादन की एक OS धागा का उल्लेख करने के लिए शुरू: इस बिंदु पर

std::thread t; // Does not refer to an OS thread 
//... 
t = std::thread(my_func); // t refers to the OS thread executing my_func 
संबंधित मुद्दे