QThread与QTimer和QSerial - 育儿

问题描述 投票:0回答:1

我正在尝试在不同的线程中创建一个“自包含”通信对象,以使其与GUI处理延迟隔离。

因此,在“AppCore”对象创建中,我创建一个没有父级的“CommCore”:

cAppCore::cAppCore(QObject *parent) : QObject(parent)
{
    ....
    CommCore = new cCommCore;
    (here I do signal-slot connections between CommCore and AppCore)
    ....
}

在CommCore构造函数中,我执行以下操作:

cCommCore::cCommCore(QObject *parent) : QObject(parent)
{
    CommThread = new QThread(this);
    CommSerial = new QSerialPort(this);
    CommTimer = new QTimer(this);

    connect(CommSerial,&QSerialPort::readyRead,this,&cCommCore::ProcessRXByte);
    connect(CommSerial, static_cast<void (QSerialPort::*)(QSerialPort::SerialPortError)>(&QSerialPort::error), this, &cCommCore::HandleSerialError);
    connect(CommTimer, &QTimer::timeout, this,&cCommCore::TimerTimeout);

    CommTimer->start(OFFLINE_POLL_TIME);
    this->moveToThread(CommThread);
    CommThread->start(QThread::HighPriority);
}

现在我的问题:

1-可以将Thread处理程序对象作为移动对象的子对象吗?因为它是在GUI线程中创建的(在那里调用构造函数),然后移动到自己处理的线程(考虑到如果我需要对它进行任何控制,我将从CommCore对象内部处理它)

2-可以在构造函数中启动计时器(它位于计时器构造函数,GUI线程的同一个线程中),并在将所有内容移动到新线程后立即执行?

3-如果我想稍后启动定时器,唯一的方法是通过信号槽?在GUI线程中发出并连接到CommCore插槽的信号(然后将在CommCore线程中排队并执行)

4-考虑到我的CommCore对象和AppCore(GUI线程)之间的所有交互都是通过信号槽(这是线程安全的)进行的,它在概念上是正确的吗? (对象的想法将自己及其子节点移动到新线程等)

5-我的基于池的串行通信例程(由定时器定时)将屏蔽GUI处理延迟? (我的意思是,Serial和Timer对象生成的事件的生成和处理没有延迟?)

c++ multithreading qt qthread
1个回答
3
投票
this->moveToThread(CommThread);

如果没有父对象的对象将成功。所以你需要改变构造函数的签名。除此之外没关系,因为物体随着它的孩子移动......

不应该像这样启动计时器,因为它被移动到不同的线程中。您应该使用invokeMethod,使其成为执行操作的正确线程

QMetaObject::invokeMethod(CommTimer, "start");

对于您剩下的问题,所有答案都是肯定的。只要你使用信号并使用invokeMethod调用,就好像线程是从runnable池中获取并运行它们一样。

因此线程安全且不受主线程中断的影响。

© www.soinside.com 2019 - 2024. All rights reserved.