在不同的无限循环(QTimerEvent)上同步Qthreads

Sync Qthreads on different infinite loops (QTimerEvent)

本文关键字:同步 Qthreads QTimerEvent 无限循环      更新时间:2023-10-16

考虑一个Qt项目。我定义了不同的 Qthreads 来在每个类的 timerEvent 中进行计算,并在 QMainWindow 上显示结果。(A类,B类和C类相同,只是printf()的内容会改变!

这是a.h

class A : public QObject
{
    Q_OBJECT
public:
    explicit A(QObject *parent = 0);
    void timerEvent(QTimerEvent *);
private:
    int timerId;
};

A.cpp是:

A::A(QObject *parent) :
    QObject(parent)
{
    timerId = startTimer(1000);
}
void A::timerEvent(QTimerEvent *)
{
    printf("An");
}

main.cpp如下:

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);
    QThread thread_1, thread_2, thread_3;
    A objA;
    B objB;
    C objC;
    objA.moveToThread(&thread_1);
    objB.moveToThread(&thread_2);
    objC.moveToThread(&thread_3);
    thread_1.start();
    thread_2.start();
    thread_3.start();
    return a.exec();
}

请注意,我无法更改课程的布局。问题是在这些情况下如何同步我的 Qthreads?每个类的结果都没有依赖关系,但我必须确保所有结果每秒都以相同的顺序可用。例如,结果必须始终显示为 A B C A B C A B C ...谢谢!

你问的是不可能的。在线程中运行的代码的执行时间会有所不同,因为内核与OS其余部分共享,并且会有所不同以及它们处于活动状态的时间。足以使订单可能会更改,您可以保证。 大多数并发系统对这一点使用线性段,例如并行处理所有任务,将结果放入队列中,当并行部分完成后,对其进行排序(如 by 和 id),然后进行处理。

您可以在QtConcurrent中尝试MapReduce。或者尝试任务依赖关系,但这实质上是告诉系统在B后运行C,并在AB,使其按顺序运行。您需要考虑所需的排序约束。

如果你不能改变类 A、B 和 C,你仍然可以创建一个管理类,该类被移动到它的线程中,拥有 A、B 和 C 对象,有一个事件计时器,并在超时时以正确的顺序调用timerEvent()函数。

这更有意义,因为结果应该是有序的。

但是,如果这是线程同步的练习,则应将这些类包装在可以执行某种同步的类中,例如条件变量,让下一个类知道当前类已完成。