QThread内创建QUDPSocket接收并处理数据

QThread内创建QUDPSocket接收并处理数据

2023年7月15日发(作者:)

QThread内创建QUDPSocket接收并处理数据QThread内创建QUDPSocket接收并处理数据前⾔最近做项⽬,与仿真机通信。仿真机发送数据频率为1毫秒,导致Qt上位机在主线程频繁接收数据,造成界⾯卡死,因此将整个udp的通信和解析都放在线程中进⾏。connect函数与QThreadconnect函数最后⼀个参数指定了三种连接⽅式:⾃动模式、直连模式和队列模式。⾃动模式下,是使⽤的直连模式还是队列模式,主要看信号发出者和槽接收者是否在同⼀线程。如果sender和reciver对象在同⼀线程中被创建,则采⽤直连模式。如果sender和reciver对象在不同的对象中被创建,则采⽤队列模式。直连模式: 是指当信号发送时,槽函数直接被调⽤,不管reciver是那个线程创建的,都在发射信号的线程内执⾏。换句话说,在⼦线程中创建sender对象,发送信号后,不管reciver是在主线程还是⼦线程创建,都会在⼦线程中执⾏。#include

#include

#include

#include

class Dummy:public QObject

{

Q_OBJECT

public:

Dummy(){}

public slots:

void emitsig()

{

emit sig();

}

signals:

void sig();

};

class Thread:public QThread

{

Q_OBJECT

public:

Thread(QObject* parent=0):QThread(parent)

{

//moveToThread(this);

}

public slots:

void slot_main()

{

qDebug()<<"from thread slot_main:" <

}

protected:

void run()

{

qDebug()<<"thread thread:"<

exec();

}

};

#include ""

int main(int argc, char *argv[])

{

QCoreApplication a(argc, argv);

qDebug()<<"main thread:"<

Thread thread;

Dummy dummy;

QObject::connect(&dummy, SIGNAL(sig()), &thread, SLOT(slot_main()));

();

g();

return ();

}上⾯代码中,dummy和thread分别作为sender和reciver,都在同⼀个线程创建,采⽤直连模式,直接调⽤,所以slot_main()在主线程中执⾏。结果如下:main thread: 0x1a40 from thread slot_main: 0x1a40 thread thread: 0x1a48注意: 若想让slot_main()在⼦线程中执⾏,只需要将thread move到⼦线程中,改变thread的所在线程,采⽤队列模式。即将上⾯代码中“movetoThread(this);”解开注释即可。这种将线程对象移动到⼦线程的⽅案是强烈不推荐的。队列模式: 是指sender发送信号后,信号被存到信号队列中,程序继续执⾏。直到reciver所在的线程事件循环处理到该信号时,槽函数被调⽤。槽函数在reciver对象所在的线程内执⾏。#include

#include

#include

#include

class Dummy:public QObject

{

Q_OBJECT

public:

Dummy(QObject* parent=0):QObject(parent){}

public slots:

void emitsig()

{

emit sig();

}

signals:

void sig();

};

class Thread:public QThread

{

Q_OBJECT

public:

Thread(QObject* parent=0):QThread(parent)

{

//moveToThread(this);

}

public slots:

void slot_thread()

{

qDebug()<<"from thread slot_thread:" <

}

signals:

void sig();

protected:

void run()

{

qDebug()<<"thread thread:"<

Dummy dummy;

connect(&dummy, SIGNAL(sig()), this, SLOT(slot_thread()));

g();

exec();

}

};

#include ""

int main(int argc, char *argv[])

{

QCoreApplication a(argc, argv);

qDebug()<<"main thread:"<

Thread thread;

();

return ();

}代码中,thread在主线程中创建,dummy在⼦线程中创建,采⽤的是队列模式,所以槽函数slot_thread()其实在主线程中运⾏。解决⽅法有两个:⼀是将thread move到⼦线程,sender和reciver在同⼀线程,该⽅案同样不推荐。⼆是指定连接模式为直接模式,直连模式下,槽必然在sender所在的线程执⾏。只要做好sender对象和槽函数的线程同步。推荐⽅式定义⼀个普通的QObject派⽣类,然后将其对象move到QThread中。使⽤信号和槽时根本不⽤考虑多线程的存在。也不⽤使⽤QMutex来进⾏同步,Qt的事件循环会⾃⼰⾃动处理好这个。#include

#include

#include

#include

class Dummy:public QObject

{

Q_OBJECT

public:

Dummy(QObject* parent=0):QObject(parent) {}

public slots:

void emitsig()

{

emit sig();

}

signals:

void sig();

};

class Object:public QObject

{

Q_OBJECT

public:

Object(){}

public slots:

void slot()

{

qDebug()<<"from thread slot:" <

}

};

#include ""

int main(int argc, char *argv[])

{

QCoreApplication a(argc, argv);

qDebug()<<"main thread:"<

QThread thread;

Object obj;

Dummy dummy;

Thread(&thread);

QObject::connect(&dummy, SIGNAL(sig()), &obj, SLOT(slot()));

();

g();

return ();

}⽅案在线程中创建UDPserver,接收数据并解析,解析完毕后,发送信号给主线程,进⾏界⾯更新。⼦线程:void HandleDatasThread::run(){ qDebug()<<"zixiancheng:"<2) { setTableWidget(ui->recvTableWidget, recvVars); lasttime = QDateTime::currentMSecsSinceEpoch() / 1000; }}⼦线程中发送信号,主线程中处理,因此是队列模式,槽函数会在主线程中运⾏,从⽽更新界⾯。通过普通的Object,movetothread的⽅式暂不介绍,有时间再整理。

发布者:admin,转转请注明出处:http://www.yc00.com/web/1689408669a243323.html

相关推荐

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信