QT5(16)多线程 Thread

忘是亡心i 2021-06-24 14:36 431阅读 0赞

推荐一博客
Qt提供两种多线程方式。一种继承QThread类;另一种采用movetothread。在Qt中采用事件循环(QEvenLoop)处理时间。

一、继承QThread

Qt线程中默认run函数调用exec()执行事件循环。但是如果继承的run函数没有启动事件循环,run函数就不会阻塞。如果我们需要启动线程内的事件循环,就需要手动执行exec()。
注意继承自QThread的类在子线程中只有run()函数部分能够在子线程中运行。其他部分还是在主线程中运行。

  1. #include <QtCore>
  2. class Thread : public QThread { private: void run() { qDebug()<<"From worker thread: "<<currentThreadId(); } }; int main(int argc, char *argv[]) { QCoreApplication a(argc, argv); qDebug()<<"From main thread: "<<QThread::currentThreadId(); Thread t; QObject::connect(&t, SIGNAL(finished()), &a, SLOT(quit())); t.start(); return a.exec(); }

如果run函数没有启用事件循环,那么一般情况下我们通过设置flag来结束进程。启用事件循环exec()后,线程不断做着循环遍历事件队列的工作,调用QThread的quit()或exit()方法使停止线程,尽量不要使用terminate(),会造成资源不能释放,甚至互斥锁还处于加锁状态。其中quit与terminate是槽,可以直接用信号连接关闭线程。线程被终止时,所有等待该线程Finished的线程都将被唤醒。

  1. #include "QThread"
  2. #include "QMutexLocker"
  3. #include "QMutex"
  4. class Thread:public QThread
  5. {
  6. Q_OBJECT
  7. public:
  8. Thread();
  9. void stop();
  10. private:
  11. bool m_stopFlag;
  12. QMutex mutex;
  13. protected:
  14. void run();
  15. };
  16. Thread::Thread()
  17. {
  18. m_stopFlag = false;
  19. }
  20. void Thread::stop()
  21. {
  22. QMutexLocker locker(&mutex);
  23. m_stopFlag = true;
  24. }
  25. void Thread::run()
  26. {
  27. while(1){
  28. {
  29. QMutexLocker locker(&mutex);
  30. if(m_stopFlag)
  31. break;
  32. }
  33. qDebug()<<"This is in thread["<<currentThreadId()<<"]."<<(int)currentThread();
  34. sleep(2);
  35. }
  36. m_stopFlag = false;
  37. }

二、movetothread

目前的推荐做法:子类继承QObject,然后使用movetothread将对象交给子线程,当信号发出后,Qt会将SLOT函数提交给子线程,放在子线程中执行。类的SLOT的函数都能够在线程中执行。

  1. include <QtCore>
  2. class Worker : public QObject { Q_OBJECT private slots: void onTimeout() { qDebug()<<"Worker::onTimeout get called from?: "<<QThread::currentThreadId(); } }; #include "main.moc" int main(int argc, char *argv[]) { QCoreApplication a(argc, argv); qDebug()<<"From main thread: "<<QThread::currentThreadId(); QThread t; QTimer timer; Worker worker; QObject::connect(&timer, SIGNAL(timeout()), &worker, SLOT(onTimeout())); timer.start(1000); worker.moveToThread(&t); t.start(); return a.exec(); }

三、connect最后一个参数


































参数 解释
Qt::AutoConnection 默认连接方式,如果信号与槽在同一线程,等同于直接连接;在不同线程,等同于队列连接。
Qt::DirectConnection 无论槽函数所属对象在哪个线程,槽函数都在信号的线程内执行,使用该连接,槽将会不在线程执行。
Qt::QueuedConnection 槽函数在对象的当前线程中按照队列顺序执行。如果线程停止,就会等待下一次启动线程时再按队列顺序执行。
Qt:: BlockingQueuedConnection 只有槽函数在线程执行完才会返回,否则发送线程也会等待。
Qt::UniqueConnection 与AutoConnect相同,只是不能重复连接相同的信号和槽。
Qt::AutoCompatConnection 兼容老版本

附上练手的百度私链破解程序(已失效,目前多次密码出错,链接404错误。)

发表评论

表情:
评论列表 (有 0 条评论,431人围观)

还没有评论,来说两句吧...

相关阅读

    相关 线——Thread

    进程(Process):“正在执行的程序”,程序进入内存运行就变成了一个进程。一个进程会产生多个线程。 多线程(Multithread):一个进程中同时存在几个执行体。单线程

    相关 线Thread

    -------------------- \\java中的线程分类 User Thread 用户线程 运行在前台,执行具体任务: 比如程序的主线程、连接网络的子线程等等

    相关 Thread实现线

    运行下面的代码,我们会发现T1、T2交替执行。这是实现多线程最简单的方式,它的局限性在于如果当前类已经继承了别的类,就无法使用这种方式来实现多线程了,因为java中只能单继承。