18

アプリケーションが、CPU コア/スレッドの数よりも多い数の複数のスレッドで関数を実行する必要があるとします。1 つの方法はQtConcurrent、最大スレッド数を使用して設定することです。

MyClass *obj = new MyClass;

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

for(int i=0;i<30;i++)
    QtConcurrent::run(obj, &MyClass::someFunction);

別の方法は、複数のオブジェクトを持ち、次を使用してそれらを別のスレッドに移動すること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();
}

スレッドの数は CPU コアの数よりも多いため、実行時にスレッドを異なるコア間で切り替える必要があります。

問題は、2 つのアプローチのパフォーマンスが異なるかどうかです。つまり、 の切り替えは、QThreadを使用して実行されるものとは異なりますQtConcurrent::runか?

4

2 に答える 2

17

最初の回答に同意しますが、何か追加したいです。

QThreadOS固有の機能を実行するだけの低レベルクラスです。とは何QtConcurrentですか? 答えはQtソースコードにあります。

第 1 レベル:実行

QFuture<T> run(T (*functionPointer)())  
{
        return (new StoredFunctorCall0<T, T (*)()>(functionPointer))->start();
}

2番目:

struct StoredFunctorCall0: public RunFunctionTask<T>    { ...

3番目:

template <typename T>
class RunFunctionTaskBase : public QFutureInterface<T> , public QRunnable
{ ...

今約QRunnable。まずQRunnable、次のQThreadPoolことを行います。

で動作する呼び出しtryStart()を呼び出すstart() (およびそれはQThread サブクラスです) であり、最終的には の呼び出しです。startThread()QThreadPoolThreadstart()QThread

そしてもちろん、この連鎖は完全ではなく、長い道のりですよね?私が知っているように、抽象化を使用すると、抽象化のペナルティがあります (QtConcurrentより大きなペナルティがありますQThread) が、最終結果は同じですQThread

于 2015-06-06T08:28:37.330 に答える