2012-12-19 19 views
11

से विधि क्रियान्वित मैं कोड निम्नलिखित है:क्यों QMetaObject :: invokeMethod का उपयोग करते समय धागा

class A : public QObject 
{ 
    Q_OBJECT 
public: 
    A() : QObject() 
    { 
     moveToThread(&t); 
     t.start(); 
    } 
    ~A() 
    { 
     t.quit(); 
     t.wait(); 
    } 

    void doSomething() 
    { 
     QMetaObject::invokeMethod(this,"doSomethingSlot"); 
    } 
public slots: 
    void doSomethingSlot() 
    { 
     //do something 
     emit ready(); 
    } 
signals: 
    void ready(); 
private: 
    QThread t; 
} 

सवाल क्यों doSomething से यह QMetaObject::invokeMethod के माध्यम से फोन किया जाना चाहिए। मुझे पता है कि कनेक्शन प्रकार के साथ कुछ है। क्या कोई यह बता सकता है कि हुड के नीचे क्या है?

+1

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

+0

पूर्ण स्पष्टीकरण के लिए [इस दस्तावेज़] को पढ़ें [http://doc.qt.digia.com/4.2/threads.html#per-thread-event-loop) –

+0

@MarekR: क्या समस्याएं हैं? मुझे यह समाधान http://stackoverflow.com/questions/13878745/correct-way-of-threading-in-qt – krzych

उत्तर

23

आप निर्दिष्ट नहीं किया है के रूप में एक Qt::ConnectionType, विधि Qt::AutoConnection के रूप में जिसका अर्थ है कि यह तुल्यकालिक द्वारा सक्रिय किया जाएगा (एक सामान्य समारोह कॉल की तरह) अगर वस्तु की धागा आत्मीयता वर्तमान धागा है एसिंक्रोनस रूप से सक्रिय किया जाएगा, और अन्यथा। "असीमित रूप से" का अर्थ है कि QEvent का निर्माण किया गया है और संदेश कतार पर धक्का दिया गया है, और ईवेंट लूप तक पहुंचने पर संसाधित किया जाएगा।

QMetaObject::invokeMethod का उपयोग करने का कारण अगर प्राप्तकर्ता ऑब्जेक्ट किसी अन्य थ्रेड में हो सकता है, तो किसी अन्य थ्रेड में किसी ऑब्जेक्ट पर सीधे स्लॉट को कॉल करने का प्रयास भ्रष्टाचार या खराब हो सकता है यदि यह गैर-थ्रेड-सुरक्षित डेटा तक पहुंच या संशोधित करता है।

+0

आपका मतलब है कि अगर मैं किसी अन्य धागे से एडोसोमिंग() का उपयोग करता हूं तो इससे भ्रष्टाचार हो सकता है? ऐसा क्यों? क्या आप तंत्र का वर्णन भी कर सकते हैं? उदाहरण के लिए – krzych

+1

@krzych उदाहरण के लिए, यदि आप एक ही समय में एक क्यूस्ट्रिंग से पढ़ते हैं तो एक और थ्रेड इसे संशोधित कर रहा है, तो यह एक असंगत स्थिति में प्रतीत होता है, जिससे अमान्य सूचक को अप्रत्यक्ष किया जा सकता है। – ecatmur

18

मैं इस चाल की तरह है:

void A:doSomethingSlot() 
{ 
    if (thread()!=QThread::currentThread()) { 
     QMetaObject::invokeMethod(this,"doSomethingSlot", Qt::QueuedConnection); 
     return; 
    } 
    // this is done always in same thread 
    ... 
    emit ready(); 
}