QT中心跳机制多线程时定时器如何使用?

在server端中添加心跳机制,15秒后无数据包时判断客户端状态为断开连接。

在clientthread.cpp中使用定时器时,在run函数中初始化了定时器,在槽函数中stop了定时器。但是会报QObject::killTimer: Timers cannot be stopped from another thread;

原因是,run函数是属于子线程的,而槽函数不属于。但是要如何在槽函数中关闭定时器呢?(错误处代码在最后面

 

///clientthread.cpp

#include "clientthread.h"

ClientThread::ClientThread(qintptr socketDescriptor, QObject *parent) : QThread(parent)
{
    m_socketDescriptor=socketDescriptor;
}

void ClientThread::run()
{
    m_socket=new QTcpSocket;
    m_timer=new QTimer;
    m_timer->setInterval(1000);
    m_socket->setSocketDescriptor(m_socketDescriptor);
    connect(m_socket,SIGNAL(readyRead()),this,SLOT(readSlot()));
    connect(m_timer,SIGNAL(timeout()),this,SLOT(doheart()));
    m_timer->start();
    exec();
}

void ClientThread::readSlot()
{
    count=0;//有数据包时,重置心跳数
    QByteArray ricvByte=m_socket->readAll();
    QString str=ricvByte.toStdString().c_str();
    qDebug()<<str;
    QStringList strlist=str.split("$");
    if(strlist[0]=="heartPackage")//区分消息类型
    {
        qDebug()<<"this is heart Package";
    }
    else {
        qDebug()<<"this is msg Package";
    }
}

//心跳执行与判断,15秒无数据包判断为断开连接
void ClientThread::doheart()
{
    count++;
    qDebug()<<count;
    if(count>15)
    {
        qDebug()<<"客户端断开连接("<<m_socketDescriptor<<")";
        count=0;
        m_timer->stop();//这里使用定时器会报QObject::killTimer: Timers cannot be stopped from another thread
    }
}

QThread对象本身不在QThread表示的线程里,只有run函数在子线程里跑
所以doheart是跑在Server所在线程里的,而m_timer在QThread所表示的线程里,导致报错

最好的解决方案:ClientThread不再继承QThread,改为继承QObject,run变为槽函数,并添加Signal started()
创建线程的代码(在server中的incomingConnection函数里)改成下面这样

  1. ClientThread *clt = new ClientThread;
  2. QThread *th = new QThread(this);
  3. clt->moveToThread(th);
  4. connect(clt, &ClientThread::started, clt, &ClientThread::run, Qt::QueuedConnection);
  5. connect(th, &QThread::finished, clt, &ClientThread::deleteLater);
  6. th->start();
  7. emit clt->started();

run函数中所有创建的QObject子类都带上parent,这样可以在deleteLater时一并销毁。

完整可用的程序(有注释,可运行)

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值