• Qt 多线程实现的两种方式 线程实现


    简述两种实现方式

    Qt提供了一个管理线程的类:QThread。

    • 子类化QThread并重新实现run().
    • 使用worker-object通过QObject::moveToThread将它们移动到线程中

    简介QThread类

    一、公共槽函数:

    1)start():开始线程的执行,内部调用run()函数,run()又调用exec()。

    2)quit():告诉线程的事件循环停止运行,并返回0(成功),等价于调用exit(0);

    3)terminiate():「不推荐使用该函数」终止线程的执行。线程可能不会立即终止,取决于操作系统的调度。

    二、信号:

    1)started():在start()之后,在run()之前发射。

    2)funished():在线程将要停止执行时发射。发射时,线程已经停止事件循环。不再执行新的事件,但是deferred deletion事件除外。可以把该信号连接到本线程中的对象的deleteLater()槽中。

    三、公共函数:

    wait():等待线程停止执行,通常和quit()配合使用

    1. void msleep(unsigned long msecs) [static]
    2. 强制当前线程睡眠msecs毫秒。
    3. void sleep(unsigned long secs) [static]
    4. 强制当前线程睡眠secs秒。
    5. void usleep(unsigned long usecs) [static]
    6. 强制当前线程睡眠usecs微秒。
    7. bool wait(unsigned long time = ULONG_MAX)
    8. 线程将会被阻塞,等待time毫秒。和sleep不同的是,如果线程退出,wait会返回

      使用 moveToThread 方式 :

    first.创建一个 QThread 和 QWorker (继承自 QObject) 类对象;

    second. 使用 moveToThread 函数移动到 thread 中运行;

    third.   通过 thread 类 start 信号和 worker 槽函数绑定;

    four.   调用 thread 类 start 信号 ,运行;

    1. QThread* thread = new QThread();
    2. WorkObject* worker = new WorkObject();
    3. worker->moveToThread(thread);
    4. QObject::connect(thread, SIGNAL(started()), worker, SLOT(doWork()));
    5. thread->start();

    实现代码:

    workobject.h

    1. #ifndef WORKOBJECT_H
    2. #define WORKOBJECT_H
    3. #include
    4. #include
    5. #include
    6. class WorkObject : public QObject
    7. {
    8. Q_OBJECT
    9. public:
    10. explicit WorkObject(QObject *parent = nullptr);
    11. signals:
    12. public slots:
    13. void doWork();
    14. };
    15. #endif // WORKOBJECT_H

     workobject.cpp

    1. #include "workobject.h"
    2. WorkObject::WorkObject(QObject *parent) : QObject(parent)
    3. {
    4. }
    5. void WorkObject::doWork()
    6. {
    7. qDebug() << "doWork thread id:" << QThread::currentThreadId();
    8. }

    main.cpp

    1. #include
    2. #include "workobject.h"
    3. int main(int argc, char *argv[])
    4. {
    5. QCoreApplication a(argc, argv);
    6. qDebug() << "main thread id:" << QThread::currentThreadId();
    7. QThread* thread = new QThread();
    8. WorkObject* worker = new WorkObject();
    9. worker->moveToThread(thread);
    10. QObject::connect(thread, SIGNAL(started()), worker, SLOT(doWork()));
    11. QObject::connect(thread, SIGNAL(finished()), thread, SLOT(deleteLater()));
    12. thread->start();
    13. return a.exec();
    14. }

    运行结果:

     可以看到,doWork 执行在子线程;

    方式二 子类化QThread

    继承自 QThread 类,覆写 run 函数。此实现方法只有 run 函数内的代码是运行在子线程内

    mythread.h

    1. #ifndef MYTHREAD_H
    2. #define MYTHREAD_H
    3. #include
    4. #include
    5. class MyThread : public QThread
    6. {
    7. Q_OBJECT
    8. public:
    9. MyThread(QObject* parent = nullptr);
    10. ~MyThread();
    11. protected:
    12. void run() override;
    13. public:
    14. void stop();
    15. private:
    16. bool exitflag;
    17. };
    18. #endif // MYTHREAD_H

    mythread.cpp

    1. #include "mythread.h"
    2. MyThread::MyThread(QObject* parent) : QThread(parent)
    3. {
    4. }
    5. MyThread::~MyThread()
    6. {
    7. }
    8. void MyThread::run()
    9. {
    10. exitflag = true;
    11. while(exitflag)
    12. {
    13. qDebug() << "MyThread thread id:" << QThread::currentThreadId();
    14. sleep(1);
    15. }
    16. }
    17. void MyThread::stop()
    18. {
    19. exitflag = false;
    20. if(isRunning())
    21. {
    22. exit();
    23. wait();
    24. }
    25. }

    main.cpp

    1. #include
    2. #include "workobject.h"
    3. #include "mythread.h"
    4. int main(int argc, char *argv[])
    5. {
    6. QCoreApplication a(argc, argv);
    7. qDebug() << "main thread id:" << QThread::currentThreadId();
    8. MyThread* myThread = new MyThread();
    9. myThread->start();
    10. return a.exec();
    11. }

    输出:

    1. main thread id: 0x700
    2. MyThread thread id: 0x4ffc
    3. MyThread thread id: 0x4ffc
    4. MyThread thread id: 0x4ffc

  • 相关阅读:
    智能仓储物流系统(Wms)系列-收货单
    17.11 JDBC 2.0 操作(血干JAVA系类)
    西南科技大学派森全套作业
    cookie以及Storage的共同点、区别与使用
    数字拼图游戏代码
    【高等数学基础进阶】定积分与反常积分-反常积分
    如何使用Arduino IDE对STM32F103C8T6进行编程
    Centos7 Docker&Docker-Compose安装教程
    java-php-python-ssm学术会议信息网站计算机毕业设计
    linux-伪首部校验和 和 icmpv6 socket组播
  • 原文地址:https://blog.csdn.net/q610098308/article/details/125872648