QT之QThread多线程编程

本节先讲解QThread,后续在讲后续几种。重点在于讲解,项目中遇到的问题,和解决办法。

class mythread:public QThread{

     Q_OBJECT   //因为QThread继承自QObject,所以要在子线程中实现信号,槽,就加上这一句。

protected:

      void run();

}

具体以实际开发为准,例子以串口通信为准,重点在于主线程接受数据,子线程解析数,至于串口通信请看串口通信章节。

MainWindow :: MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    serial=new QSerialPort;
    //串口程序省略.......
    thread=new mythread;
    connect(serial, SIGNAL(readyRead()), this, SLOT(read_serial()));   
}
1:先解释为什么thread->start(),在接受数据的时候调用,而不是在创建线程的时候调用,因为在现实生活中,
数据传输是有延迟的,不可能一次性发送完毕,
如果:start()是在创建的时候调用,而数据有延迟多次接受才完成,那么第一次接受的数据会在run()函数里面的
执行,而第二次,第三次因为没有再次调用start(),所以 run()函数不会执行,
解决办法:在每次接受到数据的时候调用start(),从而执行run()函数。


2:上面说过一帧数据会分多次接收,这就是理论和实际情况的差距,既然主线程接受数据,子线程解析数据,那么
就会发生资源抢占,个人建议用信号量,在文档里把主次线程比作,生产者,消费者。
当主线程接受到一个字节的数据的时候,生产者会默认+1,当执行次线程的时候,生产者会-1.这可能是理想状态,
有可能主线程接受10个字节,次线程消费2个字节,这样生产的过快,消费的慢,为了防止生产的数据会覆盖掉
还没来得及消费的数据,这会只要生产者的容量达到4096我们设置的容量,生产者就会阻塞,不再接受数据,反过来
生产的慢,消费的快,为了避免解析垃圾数据,消费者也会阻塞。所以既解决了资源抢占,也解决了解析数据
这一块的难点,环buf机制。

说明:这里面的字节数根据需求定,默认是1,
freeSpace.acquire(int num=1);
usedSpace.release(int num=1);


QSemaphore freeSpace(4096); //生产者的最大容量,
QSemaphore usedSpace(0); //消费者消费的容量
void MainWindow::read_serial()
{  
    QByteArray buf ;
    buf=serial->readAll();
   if(!buf.isEmpty())
     {
       freeSpace.acquire();
       //枷锁
        splite_str+=buf.toHex(); //splite_str为全局变量。
       //解锁
       usedSpace.release();
     }
    buf.clear();
    thread->start();
}


void mythread::run()
{
        usedSpace.acquire();
        //枷锁
         QString str=splite_str.toLower();
         //splite_date(str);
        //解锁
        freeSpace.release();
    
    
}







  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值