Usando o mecanismo multithreading Qt para realizar o recebimento e envio de fluxos de dados seriais duplos

Com base no artigo anterior, escrevi um programa de caixa de diálogo que pode enviar e receber dados de duas portas seriais ao mesmo tempo, e cada porta serial é implementada em um sub-thread separado. Adicionado um botão para limpar a edição.

1 Interface principal do programa

Insira a descrição da imagem aqui

2 Os números de thread dos dois threads filhos (saída nas informações de depuração)

Insira a descrição da imagem aqui
O número de ID do thread principal é 0x179c. As duas classes de sub-thread de porta serial são construídas no thread principal. A porta serial inicia e recebe dados em seus respectivos sub-threads. Os números de ID de sub-thread são 0x14e4 e 0x5b0. A porta serial é fechada no thread principal. Isso está relacionado à configuração de conexão. código mostrado abaixo:

#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();       
    }
}

A função startPort onde a porta serial inicia e recebe dados está associada ao sinal de conexão da classe QThread, portanto, é executada no thread filho; enquanto a função closePort da porta serial não está associada a conectar, não é uma função de slot, mas executada no stopCtrl da classe SerialController. O SerialController existe no encadeamento principal, portanto, closePort é executado no encadeamento principal.
Portanto, aqui está o ponto-chave (3) no artigo anterior na verificação:
(3) Em qual thread estão os objetos controlador e trabalhador? A frase "onde você cria pertence a que pertence" se aplica a todos os lugares. A função moveToThread () é chamar a função de slot no segmento especificado. Ou seja, os objetos controlador e de trabalho estão no encadeamento principal. Exceto para a função de slot associada à conexão (e a função chamada pelo corpo da função de slot), o restante das funções de trabalho também são executadas no thread principal. O remetente desta conexão pode ser o próprio SerialController (this) ou m_serialThread
moveToThread () não "move" o objeto trabalhador inteiro para o encadeamento do controlador, mas coloca a função de slot em conexão com o encadeamento do controlador para execução. Se você não prestar atenção a este ponto, o problema de "QObject :: Não é possível criar filhos para um pai que está em um thread diferente" provavelmente ocorrerá. Ou o "código de trabalho demorado" ainda está em execução no thread principal.

Acho que você gosta

Origin blog.csdn.net/SmartTiger_CSL/article/details/104383717
Recomendado
Clasificación