Qt多线程-QThread
本文标题:Qt多线程-QThread 本文地址:http://techieliang.com/2017/12/592/
1. 介绍
QThread是Qt提供的线程类,每一个QThread均可管理一个线程。
其具有两种使用方式:1、继承为QThread的子类;2、继承为QObject的子类,并使用QObject::moveToThread将此对象移到线程中运行
QThread提供了如下基本函数:
线程启动:start()运行一次
线程终止:terminate 终止线程,强制终止线程但会依据操作系统的调度策略,可能不是立即终止,最好用wait等待
quit退出线程,也可以调用exit,效果相同,会正常终止线程。
线程状态查询:isRunning是否正在运行,isFinished是否运行完成
线程状态信号:started线程启动时发出,finished线程结束时发出
其他:wait阻塞方式等待线程结束,调用此函数会将调用指令所在函数阻塞
建议对finished信号建立对应槽,实现线程结束后操作,而不是使用wait等待
更多详细说明见官方文档
1.1. 线程优先级
start函数有一个参数是线程优先级,此处使用的默认参数,若未设置也可以调用setPriority函数设置优先级,优先级分为以下几类:
| Constant | Value | Description |
|---|---|---|
QThread::IdlePriority |
0 |
scheduled only when no other threads are running. |
QThread::LowestPriority |
1 |
scheduled less often than LowPriority. |
QThread::LowPriority |
2 |
scheduled less often than NormalPriority. |
QThread::NormalPriority |
3 |
the default priority of the operating system. |
QThread::HighPriority |
4 |
scheduled more often than NormalPriority. |
QThread::HighestPriority |
5 |
scheduled more often than HighPriority. |
QThread::TimeCriticalPriority |
6 |
scheduled as often as possible. |
QThread::InheritPriority |
7 |
use the same priority as the creating thread. This is the default. |
1.2. 线程休眠
sleep秒休眠、msleep毫秒休眠、usleep微秒休眠
2. 基本使用
2.1. 建立QThread子类法
- //mythread.h
- #pragma once
- #include <QThread>
- #include <QDebug>
- class MyThread : public QThread {
- Q_OBJECT
- protected:
- void run() {
- while(1) {
- num++;
- qDebug()<<num<<"thread start:"<<QThread::currentThreadId();
- msleep(500);
- qDebug()<<num<<"thread end:"<<QThread::currentThreadId();
- }
- }
- private:
- int num = 0;
- };
- //main.cpp
- #include <QCoreApplication>
- #include <QThread>
- #include <QDebug>
- #include "mythread.h"
- int main(int argc, char *argv[]) {
- QCoreApplication a(argc, argv);
- qDebug()<<"Main:"<<QThread::currentThreadId();
- MyThread m;
- m.start();
- QThread::sleep(5);
- m.terminate();
- m.wait();
- return 0;
- }
上述代码测试了线程启动、强制停止以及currentthreadid获取当前线程id。
还可以使用currentthread获取当前线程指针函数
2.2. moveToThread方法
- #pragma once
- #include <QThread>
- #include <QDebug>
- class MyThread : public QObject {
- Q_OBJECT
- public slots://注意要用槽函数
- void start() {
- qDebug()<<"thread end:"<<QThread::currentThreadId();
- }
- };
- #include <QCoreApplication>
- #include <QThread>
- #include <QDebug>
- #include "mythread.h"
- int main(int argc, char *argv[]) {
- QCoreApplication a(argc, argv);
- qDebug()<<"Main:"<<QThread::currentThreadId();
- QThread thread;
- MyThread m;
- m.moveToThread(&thread);
- QObject::connect(&thread,SIGNAL(started()),&m,SLOT(start()));
- thread.start();
- return 0;
- }
3. 线程同步
3.1. QMutex互斥量
通过lock,unlock实现加锁、解锁
使用tryLock尝试加锁,会返回加锁成功与否,同时可设置超时时间。
注意在lock以后,任意return前必须进行unlock,否则会造成死锁
3.2. QMutexLocker
建立一个QMutex,通过QMutexLocker locker(&mutex);可以实现对mutex的自动处理,后续不需要自行进行lock和unlock,避免多个return情况下出现遗忘。
帮助文档范例:
只是用QMutex的代码:
- int complexFunction(int flag) {
- mutex.lock();
- int retVal = 0;
- switch (flag) {
- case 0:
- case 1:
- retVal = moreComplexFunction(flag);
- break;
- case 2: {
- int status = anotherFunction();
- if (status < 0) {
- mutex.unlock();
- return -2;
- }
- retVal = status + flag;
- }
- break;
- default:
- if (flag > 10) {
- mutex.unlock();
- return -1;
- }
- break;
- }
- mutex.unlock();
- return retVal;
- }
使用QMutexLocker 代码
- int complexFunction(int flag) {
- QMutexLocker locker(&mutex);
- int retVal = 0;
- switch (flag) {
- case 0:
- case 1:
- return moreComplexFunction(flag);
- case 2: {
- int status = anotherFunction();
- if (status < 0)
- return -2;
- retVal = status + flag;
- }
- break;
- default:
- if (flag > 10)
- return -1;
- break;
- }
- return retVal;
- }
3.3. QReadWriteLock
使用QMutex无论对变量进行何种操作(读写)均会锁定变量,而实际上对于读取变量值并不需要等待,可以多个线程同时读取,此时使用QReadWriteLock可以实现多线程读,单线程写的操作。帮助文档
范例:
- QReadWriteLock lock;
- void ReaderThread::run() {
- ...
- lock.lockForRead();
- read_file();
- lock.unlock();
- ...
- }
- void WriterThread::run() {
- ...
- lock.lockForWrite();
- write_file();
- lock.unlock();
- ...
- }
3.4. QReadLocker和QWriteLocker
对于QReadWriteLock,qt也提供了类似于QMutexLocker的类,提供了对QReadWriteLock对象的托管,具体请见官方文档:
3.5. QSemaphore
Qt提供的信号量,相比于互斥量只能锁定一次,信号量可以获取多次,它可以用来保护一定数量的同种资源,可用于对缓冲区的管理。
- QSemaphore sem(5); // sem.available() == 5
- sem.acquire(3); // sem.available() == 2
- sem.acquire(2); // sem.available() == 0
- sem.release(5); // sem.available() == 5
- sem.release(5); // sem.available() == 10
- sem.tryAcquire(1); // sem.available() == 9, returns true
- sem.tryAcquire(250); // sem.available() == 9, returns false
4. 其他
4.1. 线程结束后自动销毁的方法
connect(&thread, SIGNAL(finished()), &thread, SLOT(deleteLater()));
直接将线程结束的信号与deleteLater槽连接即可,deleteLater是QObject的槽函数
Qt多线程-QThread的更多相关文章
- Qt 多线程QThread实现方法之一
基本思想 在主线程中,哪里需用多线程,就在哪里创建一个QThread实例: 把耗时操作封装到一个继承于QObject的子类(这里叫做工作类Worker)槽函数中: 创建QThread实例和Worker ...
- Qt多线程-总结QThread-QThreadPool-QtConcurrent
版权声明:若无来源注明,Techie亮博客文章均为原创. 转载请以链接形式标明本文标题和地址: 本文标题:Qt多线程-总结QThread-QThreadPool-QtConcurrent 本文 ...
- Qt 多线程和网络编程学习
一,Qt多线程类学习 QThread类,开始一个新的线程就是开始执行重新实现QThread::run(),run()是默认现实调用exec(),QThread::start()开始线程的执行,run( ...
- Qt之QThread(深入理解)
简述 为了让程序尽快响应用户操作,在开发应用程序时经常会使用到线程.对于耗时操作如果不使用线程,UI界面将会长时间处于停滞状态,这种情况是用户非常不愿意看到的,我们可以用线程来解决这个问题. 前面,已 ...
- [转] Qt 多线程学习
Qt 多线程学习 转自:http://www.cnblogs.com/IT-BOY/p/3544220.html 最近的项目上用到了关于多线程的知识,自己也比较感兴趣,所以就拿了那本<C++ G ...
- 解析Qt中QThread使用方法
本文讲述的是在Qt中QThread使用方法,QThread似乎是很难的一个东西,特别是信号和槽,有非常多的人(尽管使用者本人往往不知道)在用不恰当(甚至错误)的方式在使用QThread,随便用goog ...
- QT多线程笔记
1.QT多线程涉及到主线程和子线程之间交互大量数据的时候,使用QThread并不方便,因为run()函数本身不能接受任何参数,因此只能通过信号和槽的交互来获取数据,如果只是单方面简单交互数据还过得去, ...
- Qt线程QThread简析(8个线程等级,在UI线程里可调用thread->wait()等待线程结束,exit()可直接退出线程,setStackSize设置线程堆栈,首次见到Qt::HANDLE,QThreadData和QThreadPrivate)
QThread实例代表一个线程,我们可以重新实现QThread::run(),要新建一个线程,我们应该先继承QThread并重新实现run()函数. 需要注意的是: 1.必须在创建QThread对象之 ...
- Qt多线程-QtConcurrent并行运算高级API
版权声明:若无来源注明,Techie亮博客文章均为原创. 转载请以链接形式标明本文标题和地址: 本文标题:Qt多线程-QtConcurrent并行运算高级API 本文地址:http://tec ...
随机推荐
- else的妙用--if-else 成对出现,可以检测意外的放生,方便找bug
else用于意外情况的检测.可以写入log,或者串口打印出来. 养成这样的习惯,好处 1 提高程序稳定性,可靠性. 2 遇到bug有头绪.
- Leetcode---栈系列刷题(python3实现)----#496 下一个更大元素I
给定两个没有重复元素的数组 nums1 和 nums2 ,其中nums1 是 nums2 的子集.找到 nums1 中每个元素在 nums2 中的下一个比其大的值. nums1 中数字 x 的下一个更 ...
- Learning notes | Data Analysis: 1.1 data evaluation
| Data Evaluation | - Use Shift + Enter or Shift + Return to run the upper box so as to make it disp ...
- 20155311 《Java程序设计》实验四 (Android程序设计)实验报告
20155311 <Java程序设计>实验四 (Android程序设计)实验报告 实验内容 基于Android Studio开发简单的Android应用并部署测试; 了解Android.组 ...
- 20155318 《Java程序设计》实验一(Java开发环境的熟悉)实验报告
20155318 <Java程序设计>实验一(Java开发环境的熟悉)实验报告 一.实验内容及步骤 (一)命令行下Java程序开发 步骤一(新建文件夹): 打开windows下的cmd → ...
- Linux 用C语言实现简单的shell(1)
发一波福利,操作系统的实验内容,大家可以借鉴一下,不过我的代码可能也存在一定的问题. 因为在一开始老师是一节一节课教的,当时并不知道后面还会用输入输出重定向,管道等一系列问题,我的兴趣也不在这个方面也 ...
- Burpsuite神器常用功能使用方法总结
Burpsuite介绍: 一款可以进行再WEB应用程序的集成攻击测试平台. 常用的功能: 抓包.重放.爆破 1.使用Burp进行抓包 这边抓包,推荐360浏览器7.1版本(原因:方便) 在浏览器设置代 ...
- 20145234黄斐《java程序设计基础》第一周
教材学习内容总结 1.java是SUN公司推出的面相网络的编程语言,当时取名Oak,后改名Java. 2.Java三大平台分别为:Java SE.Java EE与Java ME. 3.Java不仅是程 ...
- day8 RHCE
12 .实现一个 web 服务器在server0上配置一个站点http://server0.example.com,然后执行以下步骤: 从http://classroom.example.com/ma ...
- PHP中的事件处理
看下面的事件类 class Event { protected static $listens = array(); /** * [listen 注册监听事件] * @param [string] $ ...