• Qt 串口通信 waitForReadyRead函数与waitForBytesWritten函数导致的内存增长问题记录


    这段时间做项目需要有一个进行快速采集信息的设备,但是在单独测试的过程中发现程序的内存占用会一直增长,也就是所谓的内存泄露问题。这个问题困扰了我们几个星期,我尝试了通过事件循环重写waitfor系列函数来解决这个问题,但是由于线程包含问题导致了新的问题。。。今天在Qt的官方论坛上搜索时发现15年就有人发现了这个问题,然后上传了bug库并得到了解决,所以特此记录。

    1.问题描述

     通过形如下面的代码进行串口的读取或者写入(高频率),会导致运行exe的内存占用不断提升,在一定时间后内存泄露到一定程度会导致软件崩溃。

    1 while (1) 
    2 {
    3     if (port.waitForReadyRead(10)) 
    4     {
    5         port->readAll();
    6     }
    7 }

    2.问题原因分析

     因为waitfor系列函数是通过readyRead()信号与bytesWritten()信号来实现的,如果产生这两个信号过快(就像上面的代码,死循环执行疯狂产生信号),会导致对应到槽函数的事件(信号到槽的执行是一种事件,我之前写过,这个事件将会到对应线程的消息队列中排队等待执行)一直在消息队列中疯狂阻塞,阻塞的结果就是消息队列不断膨胀,从而内存不断增加,直到队列到达上限导致程序崩溃。

    3.问题解决方案

     知道原理后问题解决就很简单了,说穿了就是让线程去执行消息队列中的事件而不是一直产生,而Qt专门为这种情况制定了一个函数:qApp->processEvents(),这个函数的意思就是让调用此函数的线程执行其消息队列中的事件,直至没有事件可以执行为止。可见在死循环中加上这个函数之后,相关的内存泄露问题将迎刃而解,就像下面这样:

    1 while (1) 
    2 {
    3     if (port.waitForReadyRead(10)) 
    4     {
    5         qApp->processEvents();
    6         port->readAll();
    7     }
    8 }
  • 相关阅读:
    Contains,Exists,Any,Count 比较是否存在某个元素
    RabbitMQ (十六) 消息队列的应用场景 (转)
    Quartz.NET 3.0.7 + MySql 动态调度作业+动态切换版本+多作业引用同一程序集不同版本+持久化+集群(四)
    RabbitMQ (十五) 镜像集群 + HAProxy1.7.8 负载均衡
    RabbitMQ (十四) 普通集群
    RabbitMQ (十三) 集群+单机搭建(window)
    (转) HA的几种方案
    RabbitMQ (十二) 消息确认机制
    RabbitMQ (十一) 消息确认机制
    VIM操作
  • 原文地址:https://www.cnblogs.com/ybqjymy/p/14429220.html
Copyright © 2020-2023  润新知