在项目中,一个QThread对象管理了一个线程。一般来说,线程的执行从run()函数开始。在Qt中,有两种方式,第一个种是继承QThread重写run()函数,第二种是继承QObject函数添加耗时操作,然后在调用QObject::moveToThread()函数。Qt中现在比较推荐使用moveToThread()。

当线程开始或结束的时候,QThread会通过started()和finished()信号来通知,或者你也可以使用isRunning()和isFinished()来查询线程的状态。你也可以调用exit()或quit()来停止线程。在极端情况下,你可能使用terminate()来强制终止一个正在执行的线程。

QObject::moveToThread()使用示例(帮助文档中的):

class Worker : public QObject{Q_OBJECTpublic slots:void doWork(const QString &parameter) {QString result;/* ... here is the expensive or blocking operation ... */emit resultReady(result);}signals:void resultReady(const QString &result);};class Controller : public QObject{Q_OBJECTQThread workerThread;public:Controller() {Worker *worker = new Worker;worker->moveToThread(&workerThread);connect(&workerThread, &QThread::finished, worker, &QObject::deleteLater);connect(this, &Controller::operate, worker, &Worker::doWork);connect(worker, &Worker::resultReady, this, &Controller::handleResults);workerThread.start();}~Controller() {workerThread.quit();workerThread.wait();}public slots:void handleResults(const QString &);signals:void operate(const QString &);};

需要注意的是Worker一定要继承自QObject,否则调用就在同一个线程中,可以使用QThread::currentThreadId()来判断是否在哪个线程中。该调用方式中,工作线程槽中的代码会在单独的线程中执行。同时,你可以自由的将工作者线程中的槽或信号连接到任何对象的任何信号。因为队列连接的机制,该跨不同线程连接信号和槽的方式是安全的。

另一种使用线程的方式是继承QThread重写run()函数:

class WorkerThread : public QThread{Q_OBJECTvoid run() override {QString result;/* ... here is the expensive or blocking operation ... */emit resultReady(result);}signals:void resultReady(const QString &s);};void MyObject::startWorkInAThread(){WorkerThread *workerThread = new WorkerThread(this);connect(workerThread, &WorkerThread::resultReady, this, &MyObject::handleResults);connect(workerThread, &WorkerThread::finished, workerThread, &QObject::deleteLater);workerThread->start();}

在该示例中,线程将在run()函数返回后退出。除非调用exec(),否则线程不会运行任何事件循环。需要注意的是,QThread实例化位于它的旧线程中,而不是位于调用run()的新线程中。这意味着所有QThread中的队列里槽和信号的方法都将在旧线程中执行。如果你想在新线程中调用信号和槽,新的信号和槽旧不能直接在子类化的QThread中实现。即在子类化QThread时,需要记住构造函数在旧线程中执行,run()在新线程中执行。如果一个变量是从这种两个函数中访问,那么这个变量就是从两个不同的线程访问,需要检查是否是线程安全(加锁)。

Qt多线程之QThread相关推荐

  1. QT多线程之:moveToThread

    不能在另外的线程直接delete一个QObject对象,相反,你需要调用QObject::deleteLater()函数,这个函数会给对象所在线程发送一个删除的事件. QObject的线程依附性是可以 ...

  2. Qt多线程之QMutex

    QMutex类提供的是线程之间的访问顺序化. QMutex的目的是保护一个对象.数据结构或者代码段,所以同一时间只有一个线程可以访问它.(在Java术语中,它和同步关键字"synchroni ...

  3. Android多线程之ArrayBlockingQueue源码解析

    阻塞队列系列 Android多线程之LinkedBlockingQueue源码解析 Android多线程之SynchronousQueue源码解析 Andorid多线程之DelayQueue源码分析 ...

  4. Asp.Net Core 轻松学-多线程之Task快速上手

    Asp.Net Core 轻松学-多线程之Task快速上手 原文:Asp.Net Core 轻松学-多线程之Task快速上手 前言     Task是从 .NET Framework 4 开始引入的一 ...

  5. JAVA多线程之wait/notify

    本文主要学习JAVA多线程中的 wait()方法 与 notify()/notifyAll()方法的用法. ①wait() 与 notify/notifyAll 方法必须在同步代码块中使用 ②wait ...

  6. linux 线程pthread_detach,linux线程之pthread_join和pthread_detach

    在任何一个时间点上,线程是可结合的(joinable)或者是分离的(detached).一个可结合的线程能够被其他线程收回其资源和杀死.在 被其他线程回收之前,它的存储器资源(例如栈)是不释放的.相反 ...

  7. Java多线程之Callable、Future和FutureTask

    Java多线程之Callable接口 自己想总结一下的,看到一篇总结的更好的博客,就转载了,突然感觉真轻松,哈哈哈哈 文章转载于:Matrix海子:Java并发编程:Callable.Future和F ...

  8. Java多线程之Synchronized和Lock的区别

    Java多线程之Synchronized和Lock的区别 目录: 原始构成 使用方法 等待是否可以中断 加锁是否公平 锁绑定多个条件Condition 小结:Lock相比较Synchronized的优 ...

  9. Java多线程之CAS缺点

    Java多线程之CAS缺点 目录: 循环时间开销很大 只能保证一个共享变量的原子操作 引来ABA问题及解决方案(重点) 1. 循环时间开销很大 通过看源码,我们发现有个do while,如果CAS失败 ...

  10. Java多线程之CAS深入解析

    Java多线程之CAS深入解析 目录: CAS是什么 CAS底层原理Unsafe深入解析 CAS缺点 引子:蚂蚁花呗一面:讲一讲AtomicInteger,为什么要用CAS而不是synchronize ...

最新文章

  1. 《创新者》读书笔记 PB16110698 第五周(~4.5)
  2. python 字符串前加r b u f 含义
  3. java中finally与return的测试方法
  4. nginx与apache详细性能对比
  5. 【NOI2016】国王饮水记【贪心】【斜率优化】【决策单调性】
  6. 佛山市南海技师学校计算机类,佛山南海信息技术学校2021年有哪些专业
  7. springboot整合minio最新版
  8. mariadb安装_MariaDB CentOS 安装的时候如何确定 Repo 地址
  9. 抖音html动态时钟,三分钟教会!火爆抖音的“动态时钟屏保”,个性十足!
  10. 在MVC项目中设置启动页
  11. 探讨OC的内存管理 以及防止循环引用retain cycle 代理为什么用weak block为什么用copy
  12. linux c 获取进程p id,详解Linux获取线程的PID(TID、LWP)的几种方式
  13. 世间最珍贵的东西是什么
  14. dpdk对虚拟化支持研究
  15. ThinkPHP6 API接管异常
  16. openssl 交叉编译 armv7内核
  17. 迁移学习---举一反三
  18. gmtime ()函数
  19. 计算机考研怎么给老师发邮件,考研复试前,手把手教你怎么给导师发邮件!4点要注意...
  20. VMware虚拟机安装CentOS7,登录时,输入密码出现抱歉,没有奏效,请再试一遍。解决方法:

热门文章

  1. vs2010 sp1安装失败进而回滚的解决方法(本人已解决)
  2. javascript gba游戏模拟器
  3. key_beep按键控制蜂鸣器程序及流程图
  4. c#的chart标题_c#关于chart控件的使用方法
  5. 《中国通史 2016》_34_读后感
  6. 最全面测试计划书模板
  7. 【数据库系统概念】数据库基本概念
  8. Java项目经验相关常见面试题
  9. 使用HTML实现用户登录界面
  10. beescms网站渗透测试和修复意见