簡體   English   中英

Qt Worker線程-必須為每個特定任務繼承還是可以使用回調?

[英]Qt Worker thread - must I inherit for every specific task or can I use a callback?

在所有Qt QThread用法示例中,我都看到了相同的東西:

class MyThread : public QThread
{
/...
void run() { /...code
}
/...
};

因此,對於每一項不同的任務,他們都會開設一個新的班級。 是否有特定原因導致您無法使用此功能:

class GenericThraed : public QThread
{
/...
void run() { function();
}

FunctionCallback function; //Pointer to a function that you pass to the thread before starting its execution
/...
};

我的意思是,它看起來像是一種更好的替代方法,並且更加強大。 如果在線程運行之前設置函數指針,應該不會有任何問題,對嗎?

QThread不是線程,而更像是線程控制器。

本文介紹了如何真正使用QThreads。 通常,您不需要從QThread繼承,尤其是在新線程需要事件循環的情況下。

所提出的方法的一個問題是它沒有考慮在函數回調中訪問的對象的線程親和性。

例如: -

class SomeClass : public QObject
{
    Q_OBJECT

    public:
        void Increment() { m_index++; }

    private:
        int m_index = 0; // C++ 11 initialisation
};

現在,在主線程上。

SomeClass * pMyObject = new SomeClass;

如果在新線程中回調的函數具有指向pMyObject的指針並調用其Increment函數,則很可能會導致錯誤,因為對象的線程親和力與主線程(而不是新線程)有關。

因此,您可以將對象移動到新的QThread,但從本質上講,這就是我上面引用的文章所指出的:-

QThread* pThread = new QThread;
pMyObject->moveToThread(pThread);

因此,functionCallback(?)的意義何在,因為我們可以通過連接信號並啟動線程來調用增量函數:

connect(pThread, &QThread::run, pMyObject, &SomeObject::Increment);
pThread->start();

或者通過從主線程調用方法

// object has been moved to another thread, but we can still call functions
// crossing the threads, by posting to the new thread's event queue
QMetaObject::invokeMethod(pMyObject, "increment", Qt::QueuedConnection);

使用不繼承的QThread的另一個好處是,我們可以將多個QObject實例移到該類上,因此線程與對象之間不存在一對一的關系。 畢竟,擁有比處理器核心更多的線程通常沒有什么好處。

盡管Qt的許多示例可能都繼承自QThread,但我認為還是QThread開發人員之一 ,它並不總是最好的方法。

是的, QThread缺少QThread std::thread的方法,它只是啟動執行函數的線程。 不過,它不一定更健壯。 例如,如果您需要事件循環,則無法從函數內部調用exec() (請注意,如果只需要一個作業隊列QRunnable / QtConcurent::run可能更合適)。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM