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:"<
发布者:admin,转转请注明出处:http://www.yc00.com/web/1689408669a243323.html
评论列表(0条)