2012-05-19 16 views
13

मैं सीखना चाहता हूं कि नई सी ++ मानक लाइब्रेरी के साथ एकाधिक थ्रेड कैसे बनाएं और अपने हैंडल को सरणी में स्टोर करें।
मैं धागा कैसे शुरू कर सकता हूं?
मैंने जो उदाहरण देखा है, वे निर्माता के साथ धागा शुरू करते हैं, लेकिन यदि मैं सरणी का उपयोग करता हूं, तो मैं कन्स्ट्रक्टर को कॉल नहीं कर सकता।सी ++ 11 में थ्रेड ऑब्जेक्ट्स की सरणी कैसे बनाएं?

#include <iostream> 
#include <thread> 

void exec(int n){ 
    std::cout << "thread " << n << std::endl; 
} 

int main(int argc, char* argv[]){ 

    std::thread myThreads[4]; 

    for (int i=0; i<4; i++){ 
     //myThreads[i].start(exec, i); //?? create, start, run 
     //new (&myThreads[i]) std::thread(exec, i); //I tried it and it seems to work, but it looks like a bad design or an anti-pattern. 
    } 
    for (int i=0; i<4; i++){ 
     myThreads[i].join(); 
    } 

} 

उत्तर

35

कुछ भी नहीं फैंसी आवश्यक; बस असाइनमेंट का उपयोग करें। अपने लूप के अंदर,

myThreads[i] = std::thread(exec, i); 

लिखें और इसे काम करना चाहिए।

+0

लेकिन यह एक अस्थायी वस्तु बनाएगा, एक कन्स्ट्रक्टर को कॉल करेगा, असाइनमेंट करेगा, और फिर विनाशक को कॉल करेगा। राज्य असंगत हो सकता है। मैंने कोशिश की और यह काम कर रहा है, लेकिन मुझे नहीं पता कि यह कभी काम करेगा या नहीं। – Squall

+13

यह चाल semantics का उपयोग कर काम करता है। कुछ भी असंगत नहीं होगा, यह डिजाइन द्वारा काम करता है। निष्पादन के नए धागे की स्वामित्व अस्थायी से सरणी तत्व में स्थानांतरित की जाएगी, उसी स्थिति में अस्थायी रूप से निर्मित थ्रेड ऑब्जेक्ट के रूप में अस्थायी को छोड़कर यानी निष्पादन के किसी भी धागे का जिक्र नहीं किया जा सकता है, इसलिए इसे सुरक्षित रूप से नष्ट किया जा सकता है। –

-4

सी ++ 0x/सी ++ 11 के साथ, धागे के सरणी के बजाय वैक्टर का उपयोग करने का प्रयास करें; कुछ इस तरह:

vector<thread> mythreads; 
int i = 0; 
for (i = 0; i < 8; i++) 
{ 
    mythreads.push_back(dostuff, withstuff); 
} 
auto originalthread = mythreads.begin(); 
//Do other stuff here. 
while (originalthread != mythreads.end()) 
{ 
    originalthread->join(); 
    originalthread++; 
} 

संपादित करें: तुम सच में स्मृति आवंटन अपने आप को संभालने के लिए और संकेत की एक सरणी (अर्थात वैक्टर सिर्फ अपने बात नहीं कर रहे हैं) का उपयोग तो मैं valgrind अत्यधिक पर्याप्त की अनुशंसा नहीं कर सकते हैं करना चाहते हैं। इसमें मेमोरी आवंटन चेकर्स और थ्रेड चेकर्स इत्यादि हैं। इस तरह की चीज़ के लिए अनमोल। किसी भी मामले में, यहाँ मैन्युअल आवंटित धागे की एक सरणी का उपयोग कर एक उदाहरण कार्यक्रम है, और यह अपने आप में बाद को साफ (कोई मेमोरी लीक):

#include <iostream> 
#include <thread> 
#include <mutex> 
#include <cstdlib> 

// globals are bad, ok? 
std::mutex mymutex; 


int pfunc() 
{ 
    int * i = new int; 
    *i = std::rand() % 10 + 1; 

    // cout is a stream and threads will jumble together as they actually can 
    // all output at the same time. So we'll just lock to access a shared 
    // resource. 
    std::thread::id * myid = new std::thread::id; 
    *myid = std::this_thread::get_id(); 
    mymutex.lock(); 
    std::cout << "Hi.\n"; 
    std::cout << "I'm threadID " << *myid << std::endl; 
    std::cout << "i is " << *i << ".\n"; 
    std::cout << "Bye now.\n"; 
    mymutex.unlock(); 

    // Now we'll sleep in the thread, then return. 
    sleep(*i); 
    // clean up after ourselves. 
    delete i; 
    delete myid; 
    return(0); 
} 


int main() 
{ 

    std::thread * threadpointer = new std::thread[4]; 
    // This seed will give us 5, 6, 4, and 8 second sleeps... 
    std::srand(11); 
    for (int i = 0; i < 4; i++) 
    { 
     threadpointer[i] = std::thread(pfunc); 
    } 
    for (int i = 0; i < 4; i++) 
     // Join will block our main thread, and so the program won't exit until 
     // everyone comes home. 
    { 
     threadpointer[i].join(); 
    } 
    delete [] threadpointer; 
} 
+1

@ नेविन (चूंकि मैं किसी भी एल्स जवाब पर टिप्पणी नहीं कर सकता) क्या आपने valgrind --tool = helgrind के माध्यम से अपना समाधान चलाने का प्रयास किया है? मैं जीसीसी 4.5.2 पर हूं और आउटपुट से मैं देख रहा हूं कि ऐसा लगता है जैसे आप दिखा रहे हैं कि वास्तव में सी ++ 11 धागे के साथ अनिर्धारित व्यवहार क्षेत्र में आते हैं। – Kionmaru

+6

'new'/'delete' का उपयोग करने की कोई आवश्यकता नहीं है। –

+1

Kionmaru, std :: thread के साथ हेल्ग्रिंड का उपयोग करने से पहले http://stackoverflow.com/a/10624266/981959 देखें। –

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