Qt经验之实现一个多线程的串口接收类QSerialPort

Qt经验之实现一个多线程的串口接收类QSerialPort

一、多线程

Qt的多线程常见的有两种写法,一种是通过继承QThread类实现的,这种方式在以前Qt4 的版本中使用的比较多。

后来,Qt5的版本更新之后,Qt官方推荐的就是新的写法了,新的写法主要是通过继承QObject类,然后使用moveToThread()函数来实现。

二、多线程使用的场景

通常小的程序,没那么复杂的程序其实不需要使用多线程也能满足的,因为现在的计算机性能都很高了,差不多也够用了。但是在很多场景中我们还是得需要使用多线程的。

1、处理耗时的程序的时候,或者需要等待、循环等操作的时候。

2、在处理计算量比较大的代码的时候。

以上两种如果不采用多线程的方式的话,会造成界面卡顿的现象,因为Qt默认都是在一个主线程中的,如果要提高程序的响应就必须要这样做。这一点要特别的留意。

3、像一些C/S架构的软件,使用多线程并发去响应用户的请求。

4、对于多核的cpu来说,还可以提高利用率。

三、Qt中多线程要注意的事项

其实,计算机中并不是线程用的越多越好,因为多线程会涉及到线程安全的问题,这个问题本文就不分享了。另外多线程的本质是时间片段的切换,只不过cpu处理的快,像是同时在处理。就算是多核的计算机也会涉及到状态切换等问题,这些管理都是需要消耗资源的。

所以在Qt的编程中,如果不是迫不得已的情况下,一般的我们不建议线程数多于3个。

同时,我也不建议把串口接收的类封装为一个多线程的操作,因为串口和网络这些收发数据都是异步的,操作系统会调度,完全没必要再去封装为一个多线程。把接收到的数据需要计算的,耗时处理的扔到另一个线程里,这才是我们应该考虑的事情。

但是,有时候,我们迫不得已在串口或者网口接收数据后立马做一些操作,所以也会采用多线程的串口类。

在此,再次建议大家,不要把串口、网口这些接收的类封装到多线程中。

四、代码实现

下面是我封装到一个类的串口接收类,仅供大家参考。同时、TCP/UDP接收的类都可以这样封装。

头文件如下:

Class SerialRender : public QObject
{
       Q_OBJECT
public:
     explicit SerialRender( QObject *parent = 0 );
     ~SerialRender();

     void setSerialPort( QSerialPort* serialPort );
     void setPortName( QString portName );
     void setBaudRate(int baudRate);
     void setInitData();
public slots:
     void openCommSlot(bool bOpenFlag);
     void readSerialPortData();

private:
     QSerialPort* m_serialPort = NULL;
     QThread * m_thread;
     QString m_portName;
     int m_baudRate;

};

cpp文件如下:


    m_portName = portName ;
}

void SerialRender::setBaudRate(int baudRate)
{
    m_baudRate = baudRate;
}

void SerialRender::setInitData()
{
    m_thread = new QThread();
    this->moveToThread(m_thread);
    m_thread->start();
    connect( m_serialPort , SIGNAL( readyRead() ), this, SLOT(readSerialPortData())  );
}

void SerialRender::openCommSlot(bool bOpenFlag)
{  
    if ( bOpenFlag ){
        m_serialPort->flush();
        m_serialPort->setPortName(m_portName);
        m_serialPort->open(QIODevice::ReadWrite);
        m_serialPort->setBaudRate(m_baudRate );
        m_serialPort->setDataBits(QSerialPort::Data8);
        m_serialPort->setParity(QSerialPort::NoParity);
        m_serialPort->setStopBits(QSerialPort::OneStop);
        if (m_serialPort->isOpen()){
             qDebug()<<"打开成功";
        }else{
             qDebug()<<"打开失败";
        }
    }else{
        m_serialPort->flush();
        m_serialPort->close();
    }
}

void SerialRender::readSerialPortData()
{
    QByteArray data = m_serialPort->readAll();

    /***do something***/

}

本文原创作者:冯一川(ifeng12358@163.com),未经作者授权同意,请勿转载.

  • 3
    点赞
  • 35
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 11
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 11
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

冯一川

谢谢老板对我的支持!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值