Using Qt multithreading mechanism to realize the receiving and sending of dual serial data streams

On the basis of the previous article, I wrote a dialog box program that can send and receive data from two serial ports at the same time, and each serial port is implemented in a separate sub-thread. Added a button to clear edit.

1 Main program interface

Insert picture description here

2 The thread numbers of the two child threads (output in the debugging information)

Insert picture description here
The ID number of the main thread is 0x179c. The two serial port sub-thread classes are constructed in the main thread. The serial port starts and receives data in their respective sub-threads. The sub-thread ID numbers are 0x14e4 and 0x5b0. The serial port is closed in the main thread. This is related to the connect configuration. code show as below:

#include "serialcontroller.h"
#include <QDebug>

SerialController::SerialController(QObject *parent) : QObject(parent)
{
    
    
    m_portId = -1;
}

SerialController::~SerialController()
{
    
    
    if(m_serialThread.isRunning())
    {
    
    
        m_serialPort->closePort();
        delete m_serialPort;
        m_serialThread.quit();
        m_serialThread.wait();
     }

}
void SerialController::initCtrl(int portId,QString portName,long portBaud)
{
    
    
    m_portId = portId;
    m_portName = portName;
    m_portBaud = portBaud;
    qDebug()<<"Controller is running in main thread: "<<QThread::currentThreadId();

    //实例对象保存在堆上,没有父对象的指针要想正常销毁,需要将线程的 finished() 信号关联到 QObject 的 deleteLater() 让其在正确的时机被销毁

    m_serialPort = new SerialPort(m_portId,m_portName,m_portBaud);
    //m_serialPort对象不能有父对象。
    m_serialPort->moveToThread(&m_serialThread);

    connect(this,&SerialController::startRunning,m_serialPort,&SerialPort::startPort);
    connect(&m_serialThread,&QThread::finished,m_serialPort,&QObject::deleteLater);
    connect(this,&SerialController::ctrlSendData,m_serialPort,&SerialPort::write_Data);//从主线程发来的数据写入串口
    connect(m_serialPort,&SerialPort::receive_data,this,&SerialController::ctrlReceiveData);//从串口读取的数据发送给主线程
}
void SerialController::startCtrl()
{
    
    
    m_serialThread.start();
    emit startRunning();

}
void SerialController::stopCtrl()
{
    
    
    if(m_serialThread.isRunning())
    {
    
           
        m_serialPort->closePort();
        m_serialThread.quit();//会自动发送finished信号
        m_serialThread.wait();       
    }
}

The function startPort where the serial port starts and receives data is associated with the connect signal of the QThread class, so it is executed in the child thread; while the close function closePort of the serial port is not associated with connect, not a slot function, but executed in the stopCtrl of the SerialController class. SerialController exists in the main thread, so closePort is executed in the main thread.
Therefore, here is the key point (3) in the previous article in the verification:
(3) In which thread are the controller and worker objects? The phrase "where you create it belongs where you belong" applies everywhere. The moveToThread() function is to call the slot function in the specified thread. In other words, the controller and worker objects are in the main thread. Except for the slot function bound to connect (and the function called by the slot function body), the rest of the worker functions are also executed in the main thread. The sender of this connect can be the SerialController itself (this) or m_serialThread
moveToThread() does not "move" the entire worker object to the controller thread, but puts the slot function in connect to the controller thread for execution. If you don't pay attention to this point, the problem of "QObject::Cannot create children for a parent that is in a different thread" is likely to occur. Or the "time-consuming work code" is still running in the main thread.

Guess you like

Origin blog.csdn.net/SmartTiger_CSL/article/details/104383717