简体   繁体   English

Qt Worker线程-必须为每个特定任务继承还是可以使用回调?

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

In all examples of Qt QThread usage I see the same thing: 在所有Qt QThread用法示例中,我都看到了相同的东西:

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

So for every different task they make a new class. 因此,对于每一项不同的任务,他们都会开设一个新的班级。 Is there a pecific reason why you can't have this: 是否有特定原因导致您无法使用此功能:

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

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

I mean it looks like a way better alternative and way more robust. 我的意思是,它看起来像是一种更好的替代方法,并且更加强大。 If you set the function pointer before the thread runs, there shouldn't be any issues, right? 如果在线程运行之前设置函数指针,应该不会有任何问题,对吗?

QThread is not a thread, but more like a thread controller. QThread不是线程,而更像是线程控制器。

This article explains how to really use QThreads. 本文介绍了如何真正使用QThreads。 Generally, you need not inherit from QThread, especially if the new thread requires an event loop. 通常,您不需要从QThread继承,尤其是在新线程需要事件循环的情况下。

One issue with your proposed method is that it doesn't take into account the thread affinity of objects which are accessed in the function callback. 所提出的方法的一个问题是它没有考虑在函数回调中访问的对象的线程亲和性。

For example: - 例如: -

class SomeClass : public QObject
{
    Q_OBJECT

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

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

Now, on the main thread.... 现在,在主线程上。

SomeClass * pMyObject = new SomeClass;

If your function call back in the new thread has a pointer to pMyObject and calls its Increment function, it's likely to cause a fault, as the object's thread affinity is with the main thread, not the new thread. 如果在新线程中回调的函数具有指向pMyObject的指针并调用其Increment函数,则很可能会导致错误,因为对象的线程亲和力与主线程(而不是新线程)有关。

So, you can move the object to the new QThread, but essentially, that's what the article I referenced above states: - 因此,您可以将对象移动到新的QThread,但从本质上讲,这就是我上面引用的文章所指出的:-

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

So, what was the point of the functionCallback(?), as we can call the increment function either by connecting a signal and starting the thread: 因此,functionCallback(?)的意义何在,因为我们可以通过连接信号并启动线程来调用增量函数:

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

Or by invoking the method from the main thread 或者通过从主线程调用方法

// 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);

Another benefit of using QThread without inheritance is that we can move more than a single instance of a QObject to the class, so there's not a one-to-one relationship between threads and objects; 使用不继承的QThread的另一个好处是,我们可以将多个QObject实例移到该类上,因此线程与对象之间不存在一对一的关系。 after all, there's usually little benefit having more threads than processor cores. 毕竟,拥有比处理器核心更多的线程通常没有什么好处。

Although many of Qt's examples may inherit from QThread, in my opinion and one of the developers of QThread , it's not always the best method. 尽管Qt的许多示例可能都继承自QThread,但我认为还是QThread开发人员之一 ,它并不总是最好的方法。

Yes, QThread lacks a std::thread -like way of simply launching a thread executing a function. 是的, QThread缺少QThread std::thread的方法,它只是启动执行函数的线程。 It's not necessarily more robust, though. 不过,它不一定更健壮。 For instance you can't call exec() from within your function, if you ever need an event loop. 例如,如果您需要事件循环,则无法从函数内部调用exec() (Note that if you just need a job queue QRunnable / QtConcurent::run might be a better fit). (请注意,如果只需要一个作业队列QRunnable / QtConcurent::run可能更合适)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM