खोज…


टिप्पणियों

कुछ नोट जो पहले से ही यहां और यहां आधिकारिक डॉक्स में उल्लिखित हैं :

  • यदि किसी वस्तु में माता-पिता हैं, तो उसे माता-पिता के समान धागे में होना चाहिए, अर्थात उसे एक नए धागे में नहीं ले जाया जा सकता है, न ही आप किसी माता-पिता को किसी वस्तु में सेट कर सकते हैं यदि माता-पिता और वस्तु अलग-अलग धागे में रहते हैं
  • जब किसी वस्तु को एक नए धागे में ले जाया जाता है, तो उसके सभी बच्चे भी नए धागे में चले जाते हैं
  • आप केवल वस्तुओं को एक नए धागे में धकेल सकते हैं। आप उन्हें एक नए धागे में नहीं खींच सकते, यानी आप केवल उस थ्रेड से moveToThread कर सकते हैं जहां ऑब्जेक्ट वर्तमान में रह रहा है

क्यूथ्रेड का मूल उपयोग

QThread एक प्लेटफ़ॉर्म थ्रेड के लिए एक हैंडल है। यह आपको अपने जीवनकाल की निगरानी करके धागे का प्रबंधन करने देता है, और अनुरोध करता है कि यह अपना काम पूरा कर ले।

ज्यादातर मामलों में कक्षा से बाहर निकलने की सिफारिश नहीं की जाती है। डिफ़ॉल्ट run पद्धति एक ईवेंट लूप शुरू करती है जो घटनाओं को कक्षा में रहने वाली वस्तुओं के लिए भेज सकती है। क्रॉस-थ्रेड सिग्नल-स्लॉट कनेक्शन को QMetaCallEvent को लक्ष्य ऑब्जेक्ट पर QMetaCallEvent कार्यान्वित किया जाता है।

एक QObject उदाहरण को एक थ्रेड में ले जाया जा सकता है, जहां यह अपने ईवेंट को संसाधित करेगा, जैसे टाइमर इवेंट या स्लॉट / विधि कॉल।

एक सूत्र पर काम करने के लिए, पहले अपने स्वयं के कार्यकर्ता वर्ग बनाएं जो QObject से QObject । फिर इसे धागे में स्थानांतरित करें। ऑब्जेक्ट QMetaObject::invokeMethod() का उपयोग करके अपने कोड को स्वचालित रूप से चला सकता है।

#include <QObject>

class MyWorker : public QObject
{
    Q_OBJECT
public:
    Q_SLOT void doWork() {
        qDebug() << "doWork()" << QThread::currentThread();
        // and do some long operation here
    }
    MyWorker(QObject * parent = nullptr) : QObject{parent} {}
};

class MyController : public QObject
{
    Q_OBJECT
    Worker worker;
    QThread workerThread;
public:
    MyController()  {
        worker.moveToThread(&workerThread);
        // provide meaningful debug output
        workerThread.setObjectName("workerThread");
        workerThread.start();
        // the thread starts the event loop and blocks waiting for events
    }
    ~MyController()  {
        workerThread.quit();
        workerThread.wait();
    }
    void operate() {
        // Qt::QueuedConnection ensures that the slot is invoked in its own thread
        QMetaObject::invokeMethod(&worker, "doWork", Qt::QueuedConnection);
    }
};

यदि आपका कार्यकर्ता अल्पकालिक है और केवल मौजूद है, जबकि इसका काम किया जा रहा है, तो QtConcurrent::run माध्यम से थ्रेड पूल में निष्पादन के लिए एक फ़नकार या थ्रेड-सुरक्षित विधि प्रस्तुत करना सबसे अच्छा है।

QtConcurrent रन

यदि आप म्यूटेक्स या सेमाफोर जैसे जटिल क्यूटीह्रेड्स और निम्न-स्तरीय प्राइमेटिव का प्रबंधन करते हैं, तो क्यूटी समवर्ती नाम स्थान वह है जो आप खोज रहे हैं। इसमें ऐसी कक्षाएं शामिल हैं जो अधिक उच्च-स्तरीय थ्रेड प्रबंधन की अनुमति देती हैं।

आइए देखें समवर्ती रन। QtConcurrent::run() एक नए थ्रेड में फ़ंक्शन को चलाने की अनुमति देता है। आप इसका उपयोग कब करना चाहेंगे? जब आपके पास कुछ लंबा ऑपरेशन होता है और आप मैन्युअल रूप से थ्रेड नहीं बनाना चाहते हैं।

अब कोड:

#include <qtconcurrentrun.h>

void longOperationFunction(string parameter)
{
    // we are already in another thread
    // long stuff here
} 

void mainThreadFunction()
{
    QFuture<void> f = run(longOperationFunction, "argToPass");
    f.waitForFinished();
}

इसलिए चीजें सरल हैं: जब हमें किसी अन्य फ़ंक्शन को किसी अन्य थ्रेड में चलाने की आवश्यकता होती है, तो बस QtConcurrent::run , पास फ़ंक्शन और उसके मापदंडों को कॉल करें और यही वह है!

QFuture हमारे अतुल्यकालिक गणना का परिणाम प्रस्तुत करता है। QtConcurrent::run मामले में QtConcurrent::run हम कार्य निष्पादन को रद्द नहीं कर सकते।

अन्य थ्रेड्स से स्लॉट को आमंत्रित करना

जब Qt ईवेंट लूप का उपयोग ऑपरेशन करने के लिए किया जाता है और एक गैर- Qt-saavy उपयोगकर्ता को उस ईवेंट लूप के साथ सहभागिता करने की आवश्यकता होती है, तो एक और थ्रेड से नियमित इनवोकेशन को संभालने के लिए स्लॉट लिखना अन्य उपयोगकर्ताओं के लिए चीजों को सरल बना सकता है।

main.cpp:

#include "OperationExecutioner.h"
#include <QCoreApplication>
#include <QThread>

int main(int argc, char** argv)
{
    QCoreApplication app(argc, argv);

    QThread thrd;
    thrd.setObjectName("thrd");
    thrd.start();
    while(!thrd.isRunning())
        QThread::msleep(10);

    OperationExecutioner* oe = new OperationExecutioner;
    oe->moveToThread(&thrd);
    oe->doIt1(123,'A');
    oe->deleteLater();
    thrd.quit();
    while(!thrd.isFinished())
        QThread::msleep(10);

    return 0;
}

OperationExecutioner.h:

#ifndef OPERATION_EXECUTIONER_H
#define OPERATION_EXECUTIONER_H

#include <QObject>

class OperationExecutioner : public QObject
{
    Q_OBJECT
public slots:
    void doIt1(int argi, char argc);
};

#endif  // OPERATION_EXECUTIONER_H

OperationExecutioner.cpp:

#include "OperationExecutioner.h"
#include <QMetaObject>
#include <QThread>
#include <QDebug>

void OperationExecutioner::doIt1(int argi, char argc)
{
    if (QThread::currentThread() != thread()) {
        qInfo() << "Called from thread" << QThread::currentThread();
        QMetaObject::invokeMethod(this, "doIt1", Qt::QueuedConnection,
                                  Q_ARG(int,argi), Q_ARG(char,argc));
        return;
    }

    qInfo() << "Called from thread" << QThread::currentThread()
            << "with args" << argi << argc;
}

OperationExecutioner.pro:

HEADERS += OperationExecutioner.h
SOURCES += main.cpp OperationExecutioner.cpp
QT -= gui


Modified text is an extract of the original Stack Overflow Documentation
के तहत लाइसेंस प्राप्त है CC BY-SA 3.0
से संबद्ध नहीं है Stack Overflow