使用 MinGw 的 QThreads 在 windows 下无法正常工作

QThreads using MinGw doesn't work properly under windows

我正在使用 Qt 开发一个大型优化工具。为了更好地 CPU 使用,我使用 QThreads。然后我将工作对象(从 QObject 派生,包含非 QObject 数据成员)移动到线程中。使用 GCC 和 Qt 4.8

在 Linux 上一切看起来都很好,构建良好并顺利运行

但是在 Windows 下使用 MinGw 和 Qt 5.5,计算时间要长得多。看起来线程在计算中的某处阻塞并被序列化。我显示了一些调试消息以确保线程正常工作。 Windows 上似乎存在瓶颈,但 Linux 下不存在。我不认为 Qt 版本有什么不同,我宁愿认为问题是由 MinGw 引起的。 OS 是 Windows 7 和 Debian。 我使用 Qt5 的已编译 MinGw 二进制文件。

MinGw 的 Qt 构建是否需要进一步配置?或者在将工作对象移动到线程中时使用非 QObject 成员是否存在问题?这可能是 QThread 在内部使用的不同线程类型的问题吗?提前谢谢你:-)

编辑:

线程的起始对象如下所示。

for (int i = 0; i < this->numberOfCores; i++)
    {
        QThread *thread = new QThread(this);
        thread->setObjectName("Thread " + QString::number(i));
        Calculator *calculator = new Calculator(/* Skip parameters */);

        calculator->moveToThread(thread);
        connect(calculator, SIGNAL(debugInfo(DebugData)), this, SIGNAL(debugInfo(DebugData)));
        connect(this, SIGNAL(startCalculator()),
                calculator, SLOT(startCalculation()));
        connect(calculator, SIGNAL(solutionFound(Solution*)),
                this, SLOT(addSolution(Solution*)));
        connect(calculator, SIGNAL(calculationFinished()), this, SLOT(calculatorFinished()));

        thread->start(QThread::HighestPriority);

我多次使用这种方法,它总是有效。

然后计算器只计算解决方案。每个计算器都有自己的数据,并且不能存在竞争条件。他们都处理完全不同的数据。

如何启动线程?

#include <QObject>
#include <QThread>
class _Object : public QObject
{
      Q_OBJECT
public:
    explicit _Object(QObject *parent = 0);
    void _setup(QThread &th);

public slots:
    void do_stuff_you_want();
};

_Object.cpp :

#include "_object.h"

_Object::_Object(QObject *parent)  :  
QObject(parent)
{
}

void _Object::_setup(QThread &thread)
{
    connect(&thread,SIGNAL(started()),this,SLOT(do_stuff_you_want()));
}

void _Object::do_stuff_you_want(){......}

main.cpp中:

#include <all_u_need>
#include <QThread>
#include "_object.h"

int main(.. .. ..)
{
    ...

    QThread thread_obj_runns_in;
    _Object object_to_run;

    object_to_run._setup();
    object_to_run.moveToThread(&thread_obj_runns_in);

    thread_obj_runns_in.start();

    ...
    return app.exec();
}

我在使用 run() 和 QThread 子类时遇到了很多问题。 当我开始像这样使用它时,我再也没有遇到线程问题。

我想说的是:创建一个QObject并将其移动到一个线程中并且不要子类化QThread。

希望能帮到你。

在每次发出信号时,高优先级线程将与接收跨线程槽调用的低优先级线程同步。这可能是平台差异的根源:不同的内核处理临时优先级提升的方式不同,而且在 Linux 上,事件循环来自 glib,在 Windows 上则不是。当涉及到不同优先级的线程之间的同步时,它们的行为会有所不同。如果接收线程在事件循环中花费大量时间主动调度事件,它会对高优先级线程造成严重破坏。

也许与直觉相反,解决方案可能很简单而不是使计算线程具有高优先级。

无论如何,您的用户会讨厌您剥夺他们进行某些本应在后台 运行 的计算的交互性能。计算线程将抢占默认优先级 GUI 线程,系统对于交互式用户来说会感觉非常缓慢,这也适用于您自己的 UI!计算线程应该具有 较低的 优先级。这当然假设计算不用于驱动交互(例如游戏中的物理引擎);如果他们这样做了,并且您认为应用程序应得的,则必须提高整个过程的优先级。