2011-03-01 6 views
6

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

बेहतर पहले कार्यों धागा के शुरू में के लिए समारोह लिखने moveTothread (दूसरा धागा) का उपयोग करने

या

एक नया में दूसरा समारोह को परिभाषित है थ्रेड क्लास और उस थ्रेड को पर पहले धागे की शुरुआत पर कॉल करें।

+0

संबंधित: [QThread मुख्य अनुप्रयोग अवरुद्ध करना] (http://stackoverflow.com/questions/3213738/) –

उत्तर

8

moveToThread इस्तेमाल करते हुए हम एक वस्तु का धागा आत्मीयता बदल सकते हैं:
यह है कि ब्लॉग से सरल कोड है। ओपी पूछता है कि हम अलग-अलग धागे में एक ही कक्षा के दो कार्यों को कैसे चला सकते हैं।

Let वर्ग A और दो कार्यों f1 और f2

class A 
{ 
public: 
    void f1(); 
    void f2(int i); 
    void run(); // shows how we can trigger f1 and f2 in different threads 
} 

Qt पहले से ही अलग धागे में कार्यों को चलाने के लिए एक वर्ग प्रदान की है और यह QtConcurrentRun

कहा जाता है QtConcurrent::run() समारोह एक में एक समारोह चलाता है अलग धागा फ़ंक्शन का वापसी मूल्य QFuture API के माध्यम से उपलब्ध कराया गया है।

ट्रिगर किया गया फ़ंक्शन या तो बाहरी फ़ंक्शन या सदस्य फ़ंक्शन हो सकता है। इसलिए हमारे मामले में हम f1 और विभिन्न धागे में f2 शुरू करने के लिए वस्तु से ही चाहते थे कि अगर हम run()

void run() 
{ 
    // QFuture<void> because f1 is void 
    QFuture<void> future1 = QtConcurrent::run(this, &A::f1); 
    int k = 5; // Concurrent run with arguments 
    QFuture<void> future2 = QtConcurrent::run(this, &A::f2, k); 
} 

में निम्नलिखित कर सकता है इसी तरह आप समवर्ती किसी भी वर्ग के किसी भी सार्वजनिक समारोह, जैसे

QImage image = ...; 
QFuture<void> future = QtConcurrent::run(image, &QImage::invertPixels, QImage::InvertRgba); 

A a; 
QFuture<void> future1 = QtConcurrent::run(A, &A::f1); 
पर अमल कर सकता है

सूचना दो कॉल के बीच अंतर:

QtConcurrent::run() भी सदस्य के कामकाज की ओर इशारा स्वीकार करता है ऑन। पहला तर्क क्लास के उदाहरण के लिए या तो एक कॉन्स्ट संदर्भ या सूचक होना चाहिए। कॉलिंग कॉन्स सदस्य फ़ंक्शंस जब कॉन्स्ट संदर्भ द्वारा पास करना उपयोगी होता है; पॉइंटर द्वारा गुजरना के लिए उपयोगी है जो गैर-कॉन्स्ट सदस्य फ़ंक्शन को कॉल करता है जो उदाहरण को संशोधित करता है।

एक समवर्ती रूप से निष्पादित फ़ंक्शन समाप्त होने पर जांचने के लिए आपको QFutureWatcher का उपयोग करना चाहिए।

9

पियटर की तरह उत्तर दिया गया कि आपको वास्तव में सुझाए गए लिंक पर एक नज़र डालना चाहिए।
जैसा कि मैं आपकी समस्या को समझता हूं, इससे आपकी समस्या हल होनी चाहिए।

class Producer 
{ 
public: 
    Producer(); 

public slots: 
    void produce() 
    { //do whatever to retrieve the data 
     //and then emit a produced signal with the data 
     emit produced(data); 
     //if no more data, emit a finished signal 
     emit finished(); 
    } 

signals: 
    void produced(QByteArray *data); 
    void finished(); 
}; 

class Consumer 
{ 
public: 
    Consumer(); 

public slots: 
    void consume(QByteArray *data) 
    { 
     //process that data 
     //when finished processing emit a consumed signal 
     emit consumed(); 
     //if no data left in queue emit finished 
     emit finished(); 
    } 
}; 

int main(...) 
{ 
    QCoreApplication app(...); 

    Producer producer; 
    Consumer consumer; 

    producer.connect(&consumer, SIGNAL(consumed()), SLOT(produce())); 
    consumer.connect(&producer, SIGNAL(produced(QByteArray *)), SLOT(consume(QByteArray *)); 

    QThread producerThread; 
    QThread consumerThread; 
    producer.moveToThread(&producerThread); 
    consumer.moveToThread(&consumerThread); 

    //when producer thread is started, start to produce 
    producer.connect(&producerThread, SIGNAL(started()), SLOT(produce())); 

    //when consumer and producer are finished, stop the threads 
    consumerThread.connect(&consumer, SIGNAL(finished()), SLOT(quit())); 
    producerThread.connect(&producer, SIGNAL(finished()), SLOT(quit())); 

    producerThread.start(); 
    consumerThread.start(); 

    return app.exec(); 
} 
+0

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

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