具有多线程的QtConcurrent Vs QThread的多线程性能

Nej*_*jat 13 c++ qt multithreading qtconcurrent qthread

假设您的应用程序需要在多个线程中运行一个函数,其数量大于CPU核心/线程的数量.一种方法是使用QtConcurrent和设置最大线程数:

MyClass *obj = new MyClass;

QThreadPool::globalInstance()->setMaxThreadCount(30);

for(int i=0;i<30;i++)
    QtConcurrent::run(obj, &MyClass::someFunction);
Run Code Online (Sandbox Code Playgroud)

另一种方法是使用多个对象并将它们移动到不同的线程moveToThread:

for(int i=0;i<30;i++)
{
        MyClass *obj = new MyClass;
        QThread *th = new QThread();
        obj->moveToThread(th);
        connect(th, SIGNAL(started()), obj, SLOT(someFunction()) );
        connect(obj, SIGNAL(workFinished()), th, SLOT(quit()) );
        connect(th, SIGNAL(finished()), obj, SLOT(deleteLater()) );
        connect(th, SIGNAL(finished()), th, SLOT(deleteLater()) );

        th->start();
}
Run Code Online (Sandbox Code Playgroud)

由于线程数大于CPU核心数,因此在运行时应该在不同的核心之间切换线程.

问题是这两种方法是否有不同的表现?即,切换是否QThread与使用QtConcurrent::run?的切换不同?

Che*_*byl 13

我同意第一个答案,但我想补充一点.

QThread是低级类,只运行特定于操作系统的功能.什么是QtConcurrent?答案是Qt源代码.

第一级:

QFuture<T> run(T (*functionPointer)())  
{
        return (new StoredFunctorCall0<T, T (*)()>(functionPointer))->start();
}
Run Code Online (Sandbox Code Playgroud)

第二:

struct StoredFunctorCall0: public RunFunctionTask<T>    { ...
Run Code Online (Sandbox Code Playgroud)

第三:

template <typename T>
class RunFunctionTaskBase : public QFutureInterface<T> , public QRunnable
{ ...
Run Code Online (Sandbox Code Playgroud)

现在约QRunnable.当我们开始时QRunnable,QThreadPool我们做:

启动()这就要求tryStart()它要求startThread()与操作QThreadPoolThread(它是一个QThread的子类),它是最后调用start()QThread.

当然这条连锁店不是满满的,漫漫长路,不是吗?据我所知,当我们使用抽象时,我们有抽象惩罚(QtConcurrent然后有更大的惩罚QThread),但最终结果是相同的,它是QThread.


Mar*_* A. 10

简短回答:这取决于工作量的性质/逻辑.

QtConcurrent运行一个线程池,它是一个更高级别的API,不适合运行大量的阻塞操作:如果你做了很多阻塞操作,你很快就会耗尽池并让其他请求排队.在那种情况下,QThread(较低级别的构造)可能更适合于操作(每个代表一个线程).