考虑一个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 ...谢谢!
答案 0 :(得分:1)
你问的是不可能的。线程中运行的代码的执行时间会有所不同,因为核心与OS
的其余部分共享,并且它们会有所不同以及它们处于活动状态的时间。足够的订单可能会改变,你可以保证。
大多数并发系统在这一点上使用线性段,比如并行处理所有任务,将结果放入队列中,当并行部分完成时,对其进行排序(如by和id)然后进行处理。
您可以在MapReduce
中尝试QtConcurrent
。或者尝试任务依赖,但这实际上会告诉系统在C
后运行B
,在B
之后运行A
,使其顺序运行。您需要考虑您想要的订购限制。
答案 1 :(得分:0)
如果您无法更改A,B和C类,您仍然可以创建一个移动到其线程的管理类,拥有A,B和C对象,具有事件计时器和超时调用timerEvent()
按正确的顺序运行。
这更有意义,因为预期结果是有序的。
但是,如果这是一个关于线程同步的练习,你应该将这些类包装在可以进行某种同步的类中,比如条件变量,让下一个类知道当前的类已经完成。