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

时间:2016-06-02 08:35:05

标签: c++ multithreading qt infinite-loop qthread

考虑一个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("A\n");
}

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 ...谢谢!

2 个答案:

答案 0 :(得分:1)

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

您可以在MapReduce中尝试QtConcurrent。或者尝试任务依赖,但这实际上会告诉系统在C后运行B,在B之后运行A,使其顺序运行。您需要考虑您想要的订购限制。

答案 1 :(得分:0)

如果您无法更改A,B和C类,您仍然可以创建一个移动到其线程的管理类,拥有A,B和C对象,具有事件计时器和超时调用timerEvent()按正确的顺序运行。

这更有意义,因为预期结果是有序的。

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