2008-09-17 7 views
16

मुझे लगता है कि सर्वोत्तम एक सी ++ कक्षा का सदस्य है जो एक पर्थ्रेड शुरू करने के लिए है? मेरा अपना दृष्टिकोण उत्तर के रूप में अनुसरण करता है ...सी ++ कक्षा के सदस्य के रूप में धागा शुरू करने का सबसे अच्छा तरीका?

उत्तर

15

मैं आमतौर पर कक्षा के स्थिर सदस्य फ़ंक्शन का उपयोग करता हूं, और शून्य * पैरामीटर के रूप में कक्षा में पॉइंटर का उपयोग करता हूं। वह फ़ंक्शन या तो थ्रेड प्रोसेसिंग कर सकता है, या कक्षा संदर्भ के साथ एक और गैर स्थैतिक सदस्य फ़ंक्शन कॉल कर सकता है। उस समारोह में अजीब सिंटैक्स के बिना सभी वर्ग के सदस्यों को संदर्भित किया जा सकता है।

+0

रैपर फ़ंक्शन में सी लिंकेज होना चाहिए। भाषा लिंक – sellibitze

11

आप शून्य का उपयोग कर इसे bootstrap करने के लिए है * पैरामीटर:

class A 
{ 
    static void* StaticThreadProc(void *arg) 
    { 
    return reinterpret_cast<A*>(arg)->ThreadProc(); 
    } 

    void* ThreadProc(void) 
    { 
    // do stuff 
    } 
}; 

... 

pthread_t theThread; 
pthread_create(&theThread, NULL, &A::StaticThreadProc, this);
+0

के कारण मुफ्त कार्यों का फ़ंक्शन पॉइंटर्स असंगत हो सकता है क्योंकि मैं सी ++ मुद्दे में अपने वर्तमान pthread का शोध करता हूं। हालांकि, यह यहां स्थित उत्तर के साथ प्रभावी ढंग से संघर्ष नहीं करता है: http://stackoverflow.com/questions/592160/static-vs-extern-c। क्या आपको किसी भी तरह बाहरी "सी" जोड़ने की ज़रूरत नहीं है? साथ ही, StaticThreadProc में वास्तविक कार्य करने के साथ कोई समस्या है? –

23

यह केवल इस तरह, बढ़ावा पुस्तकालय का उपयोग करके किया जा सकता है:

#include <boost/thread.hpp> 

// define class to model or control a particular kind of widget 
class cWidget 
{ 
public: 
void Run(); 
} 

// construct an instance of the widget modeller or controller 
cWidget theWidget; 

// start new thread by invoking method run on theWidget instance 

boost::thread* pThread = new boost::thread(
    &cWidget::Run,  // pointer to member function to execute in thread 
    &theWidget);  // pointer to instance of class 

नोट्स:

  • यह एक साधारण वर्ग सदस्य फ़ंक्शन का उपयोग करता है। अतिरिक्त, स्थैतिक सदस्यों को जोड़ने की कोई आवश्यकता नहीं है जो आपके कक्षा इंटरफ़ेस को
  • बस स्रोत फ़ाइल में boost/thread.hpp शामिल करें जहां आप थ्रेड प्रारंभ करते हैं। यदि आप अभी भी बढ़ावा देने के साथ शुरू कर रहे हैं, तो बाकी सभी बड़े और डरावने पैकेज को अनदेखा किया जा सकता है।

सी ++ 11 में आप एक ही लेकिन बढ़ावा

बिना
// define class to model or control a particular kind of widget 
class cWidget 
{ 
public: 
void Run(); 
} 

// construct an instance of the widget modeller or controller 
cWidget theWidget; 

// start new thread by invoking method run on theWidget instance 

std::thread * pThread = new std::thread(
    &cWidget::Run,  // pointer to member function to execute in thread 
    &theWidget);  // pointer to instance of class 
+0

तो, मैं इसका विरोध नहीं कर रहा हूं ... लेकिन दुकान में कोई भी काम करता है जो मैं उपयोग करता हूं ...यह एक बड़ा प्रतिमान बदलाव होगा। इसकी एक बड़ी पुस्तकालय भी है ... इसका उपयोग शुरू करने का सबसे अच्छा तरीका क्या है ?? – jdt141

+0

ठीक है, यह वास्तव में एक पुस्तकालय नहीं है, बस इसमें शामिल है। तो आप इसका कुछ छोटा हिस्सा चुन सकते हैं जो आपकी कल्पना को पकड़ लेता है और उन शीर्षकों को शामिल करके शुरू करता है जहां आपको उनकी आवश्यकता होती है। बस कुछ अच्छी नई भाषा विशेषताएं हैं जिन्हें आप उचित और उचित मानते हैं। बढ़ावा देने के लिए – ravenspoint

+2

+1! नाइटपिक नहीं करना चाहिए, लेकिन क्या आपके चर 'cMyClass theClass' को वास्तव में' cMyClass theObject' कहा जाना चाहिए क्योंकि यह कक्षा नहीं है बल्कि सिर्फ एक उदाहरण है? मुझे लगता है कि यह स्पष्ट होगा। –

3

मैं तरीकों ऊपर उल्लिखित के तीन का इस्तेमाल किया है कर सकते हैं। जब मैं पहली बार ग में सूत्रण इस्तेमाल किया ++ मैं स्थिर सदस्य कार्यों इस्तेमाल किया है, तो दोस्त में कार्य करता है और अंत में बूस्ट पुस्तकालयों। वर्तमान में मैं बूस्ट पसंद करते हैं। पिछले कई सालों में मैं काफी बूस्ट बिगोट बन गया हूं।

बूस्ट सी ++ है क्योंकि सीपीएएन पर्ल है। :)

0

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

एक बहुत अच्छे समाधान है, जो मुसीबत का एक बहुत बचाता है:

#include <boost/thread.hpp> 

class MyClass { 
public: 
     MyClass(int i); 
     MyClass(const MyClass& myClass); // Copy-Constructor 
     void operator()() const;   // entry point for the new thread 

     virtual void doSomething();  // Now you can use virtual functions 

private: 
     int i;       // and also fields very easily 
}; 

MyClass clazz(1); 
// Passing the object directly will create a copy internally 
// Now you don't have to worry about the validity of the clazz object above 
// after starting the other thread 
// The operator() will be executed for the new thread. 
boost::thread thread(clazz);    // create the object on the stack 

अन्य बढ़ावा उदाहरण के लिए, ढेर पर धागा वस्तु बनाता है, यद्यपि वहाँ यह करने के लिए कोई मतलब नहीं है।

+0

क्या होता है यदि कक्षा में दो या दो से अधिक विभिन्न विधियां हैं जिन्हें आपको चलाने की आवश्यकता है?() ऑपरेटर का उपयोग चालाक (अच्छा है?) लेकिन क्या यह सबसे अच्छा तरीका है, बशर्ते कि आपके पास प्रति वर्ग केवल एक हो? – ravenspoint

+1

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

+0

एक तंत्र को लपेटना एक अच्छा विचार है, जो आपको कक्षा पर कई कार्यों को कॉल करने की अनुमति देता है, लेकिन आपको शायद ही इसकी आवश्यकता होगी। सबसे पहले मैंने सोचा कि यह एक अच्छा तरीका है, लेकिन फिर मैंने दुष्प्रभावों को देखा। यदि आप एक कॉपी तंत्र के साथ कुछ लागू करेंगे, तो मुझे यह पसंद आएगा। पॉइंटर के बजाय ऑब्जेक्ट को बढ़ावा देने के लिए :: बाइंड ऑब्जेक्ट को कई बार कॉपी करेगा। लेकिन अन्यथा आपको ज्यादातर मामलों में परेशानी होगी, सिंगलेट्स और कुछ 'पागल' ऑब्जेक्ट प्रबंधन – CSpille

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