2011-02-24 6 views
5

मैं Windows थ्रेड फ़ंक्शन में पॉइंटर के रूप में boost :: share_ptr को कैसे पास कर सकता हूं? निम्नलिखित कोड मान:मैं विंडोज थ्रेड फ़ंक्शन में पॉइंटर के रूप में boost :: share_ptr को कैसे पास कर सकता हूं?

test::start() 
{ 
    .... 
    _beginthreadex(NULL, 0, &test::threadRun, &shared_from_this(), 0, &threadID); 

    ... 
    ... 
} 

/*this is a static function*/ 
UINT __stdcall test::threadRun(LPVOID lpParam) 
{ 
    shared_ptr<test> k = *static_cast< shared_ptr<test>* >(lpParam); 
    ... 
} 

मुझे लगता है कि इस कोड गलत है, आपके विचार क्या है? मैं यह कैसे कर सकता हूं?

संपादित करें: मैंने बूस्ट :: weak_ptr द्वारा अपनी समस्या हल की। इस page

+2

आप बूस्ट का उपयोग क्यों नहीं करते हैं। इसके बजाए पढ़ें? – jalf

+0

मेरे पास बहुत सारे कोड हैं जो विंडोज थ्रेड के साथ काम करते हैं, वर्तमान में मेरे पास उन्हें बढ़ावा देने के लिए पर्याप्त समय नहीं है। थ्रेड, इसके अलावा, मैंने कभी भी boost.thread का उपयोग नहीं किया है। –

+3

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

उत्तर

1

मैं बढ़ावा :: weak_ptr से मेरी समस्या हल: व्यावहारिक रूप से, कॉलबैक अपने वर्ग के एक सदस्य के रूप में है संदर्भ गिनती अच्छी तरह से काम करता है।

आप boost::shared_ptr पास करना चाहते हैं आप इसे एक struct है कि घुसपैठ संदर्भ गिनती में डाल सकता है और में इसे पारित।

यह आपको यह सोचते है नहीं है सिर्फ एक कच्चे सूचक में पास करना चाहते हैं और मिल समाप्त होने पर इसे हटाने के लिए थ्रेड प्राप्त करना।

+3

यह समस्या को हल करने की गारंटी नहीं है क्योंकि wptr test :: start() में स्थानीय चर है और परीक्षण :: start() समाप्त होने पर अमान्य हो जाएगा, इसलिए समस्या तब तक वही है जब तक कि आप धागे की प्रतीक्षा न करें स्टार्ट() से बाहर निकलने से पहले पैरामीटर को "उठाएं" शुरू करें। – CashCow

1

में अपना स्वयं का उत्तर देखें, आपको reinterpret_cast का उपयोग करना चाहिए और सावधानी बरतें कि आप कम से कम एक साझा_प्टर को स्पॉन्गिंग के दौरान रखें। अन्यथा आपकी वस्तु नष्ट हो जाएगी। यही कारण है कि, जब आप shared_ptr पर पॉइंटर पास करते हैं, तो आप सामान्य पॉइंटर सुरक्षा का आनंद नहीं लेंगे और यदि आपके सभी मौजूदा साझा_प्टर नष्ट हो जाते हैं, तो जब आपका धागा उत्पन्न होता है तो इसमें एक अवैध पॉइंटर होगा।

3

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

test::start() 
{ 
    .... 
    shared_ptr<test> shPtr = shared_from_this(); 
    boost::weak_ptr<test> wPtr=shPtr; 
    _beginthreadex(NULL, 0, &test::threadRun, &wPtr, 0, &threadID); 

    ... 
    ... 
} 

/*this is a static function*/ 
UINT __stdcall test::threadRun(LPVOID lpParam) 
{ 
shared_ptr<test> k  = static_cast< boost::weak_ptr<test>* >(lpParam)->lock(); 
    ... 
} 
0

यह उन परिस्थितियों में से एक वास्तव में जहां घुसपैठ:

test::start() 
{ 
    // [...] 
    _beginthreadex(NULL, 0, &test::threadRun, this, 0, &threadID); 
    // [...] 
} 

// this is a static function 
UINT __stdcall test::threadRun(LPVOID lpParam) 
{ 
    test* self = static_cast<test*>(lpParam); 

    // do whatever you want with all the instance members :) 

    self->getMyShared(); 
    self->useMyGreatMemberMethof(); 

    // ... 
} 

my2c