版权声明:若无来源注明,Techie亮博客文章均为原创。 转载请以链接形式标明本文标题和地址:
本文标题:Qt多线程-QThreadPool线程池与QRunnable     本文地址:http://techieliang.com/2017/12/605/
文章目录

  • 1. 介绍
  • 2. QThreadPool
  •  2.1. 基本操作函数
  •  2.2. start tryStart tryTake
  •  2.3. 全局线程池
  •  2.4. 局部线程池
  • 3. QRunnable
  • 4. 范例
  •  4.1. 简单使用范例
  •  4.2. 全局线程池和局部线程池对比

1. 介绍

线程的创建及销毁需要与系统交互,会产生很大的开销。若需要频繁的创建线程建议使用线程池,有线程池维护一定数量的线程,当需要进行多线程运算时将运算函数传递给线程池即可。线程池会根据可用线程进行任务安排。

2. QThreadPool

相关帮助文档:QThreadPool

此类为Qt提供的线程池函数,使用此类只需要配置线程池的最大线程数量、线程长时间不使用的过期时间等参数,不需要进行QThread相关的操作。

此类有两种使用方式:全局线程池和局部线程池。下面首先介绍两种类型后续介绍类提供的方法

2.1. 基本操作函数

  1. int activeThreadCount() const //当前的活动线程数量
  2. void clear()//清除所有当前排队但未开始运行的任务
  3. int expiryTimeout() const//线程长时间未使用将会自动退出节约资源,此函数返回等待时间
  4. int maxThreadCount() const//线程池可维护的最大线程数量
  5. void releaseThread()//释放被保留的线程
  6. void reserveThread()//保留线程,此线程将不会占用最大线程数量,从而可能会引起当前活动线程数量大于最大线程数量的情况
  7. void setExpiryTimeout(int expiryTimeout)//设置线程回收的等待时间
  8. void setMaxThreadCount(int maxThreadCount)//设置最大线程数量
  9. void setStackSize(uint stackSize)//此属性包含线程池工作线程的堆栈大小。
  10. uint stackSize() const//堆大小
  11. void start(QRunnable *runnable, int priority = 0)//加入一个运算到队列,注意start不一定立刻启动,只是插入到队列,排到了才会开始运行。需要传入QRunnable ,后续介绍
  12. bool tryStart(QRunnable *runnable)//尝试启动一个
  13. bool tryTake(QRunnable *runnable)//删除队列中的一个QRunnable,若当前QRunnable 未启动则返回成功,正在运行则返回失败
  14. bool waitForDone(int?<i>msecs</i>?=?-1)//等待所有线程运行结束并退出,参数为等待时间-1表示一直等待到最后一个线程退出

QThread::idealThreadCount函数,会根据当前设备的硬件情况给出一个线程数量,而maxThreadCount的默认值就是此值。

setStackSize

只有在线程池创建新线程时才使用该属性的值。更改它对已经创建或运行的线程没有影响。默认值是0,这使得qthread使用操作系统默认的堆栈大小。

The value of the property is only used when the thread pool creates new threads. Changing it has no effect for already created or running threads.

The default value is 0, which makes QThread use the operating system default stack size.

maxThreadCount? reserveThread? activeThreadCount

由于reserveThread 后的线程不计入线程数量,因此可能出现activeThreadCount>maxThreadCount? 情况

Note: It is possible for this function to return a value that is greater than maxThreadCount(). See reserveThread() for more details.

2.2. start tryStart tryTake

对于start,传入的是QRunnable对象指针,传入后线程池会调用QRunnable的autoDelete() 函数,若返回true,则当此运算完成后自动释放内容,不需要后续主动判断是否运算完成并释放空间。

对于tryTake,若返回成功,不会自动释放内容,而是需要调用方主动释放,无论autodelete返回值是什么。返回false自然也不会自动delete

Attempts to remove the specified runnable from the queue if it is not yet started. If the runnable had not been started, returns true, and ownership of runnable is transferred to the caller (even when runnable->autoDelete() == true). Otherwise returns false.

Note: If runnable->autoDelete() == true, this function may remove the wrong runnable. This is known as the ABA problem: the original runnable may already have executed and has since been deleted. The memory is re-used for another runnable, which then gets removed instead of the intended one. For this reason, we recommend calling this function only for runnables that are not auto-deleting.

对于tryStart,若返回成功,等同于start,若false,则不会自动delete

注意,对于autoDelete必须在调用state/trytake之前进行修改,不要再调用以后修改,否则结果不可预测

Note that changing the auto-deletion on runnable after calling this function results in undefined behavior.

QRunnable的autoDelete默认返回true,若需要更改需要调用setAutoDelete进行更改

2.3. 全局线程池

QThreadPool提供了一个静态函数,globalInstance(),使用此方法可获取一个当前进程的全局线程池,可在多个类中共同使用一个线程池。

2.4. 局部线程池

和常规类的使用相同,可以通过? QThreadPool pool;的方式建立一个局部线程池,并由当前类维护,可保证此线程池仅供当前类应用

3. QRunnable

线程池每一个需要运行的任务均需要作为QRunnable的子类,并重写其run函数,帮助文档:http://doc.qt.io/qt-5/qrunnable.html

QRunnable只有run、autodelete、setautodelete这三个关键函数。

run内重写需要运算的内容。

autodelete用来标识是否在运行结束后自动由线程池释放空间,具体说明见上述“QThreadPool-基本操作函数-start tryStart tryTake”

4. 范例

4.1. 简单使用范例

  1. #include <QCoreApplication>
  2. #include <QThreadPool>
  3. #include <QThread>
  4. #include <QRunnable>
  5. #include <QDebug>
  6. class MyRun : public QRunnable {
  7. public:
  8. void run() {
  9. int i=3;
  10. while(i) {
  11. i--;
  12. qDebug()<<"thread start:"<<QThread::currentThreadId();
  13. QThread::msleep(500);
  14. }
  15. }
  16. };
  17. int main(int argc, char *argv[]) {
  18. QCoreApplication a(argc, argv);
  19. qDebug()<<"Main:"<<QThread::currentThreadId();
  20. QThreadPool m;
  21. MyRun *run=new MyRun;
  22. if(!run->autoDelete()) {
  23. qDebug()<<"QRunnable's autoDelete default value is not true";
  24. run->setAutoDelete(true);
  25. }
  26. qDebug()<<m.maxThreadCount()<<m.expiryTimeout();
  27. qDebug()<<m.activeThreadCount();
  28. m.start(run);
  29. qDebug()<<m.activeThreadCount();
  30. m.waitForDone();
  31. qDebug()<<m.activeThreadCount();
  32. return 0;
  33. }

结果:

  1. Main: 0xffc
  2. 4 30000
  3. 0
  4. 1
  5. thread start: 0x7e4
  6. thread start: 0x7e4
  7. thread start: 0x7e4
  8. 0

4.2. 全局线程池和局部线程池对比

  1. #include <QCoreApplication>
  2. #include <QThreadPool>
  3. #include <QThread>
  4. #include <QRunnable>
  5. #include <QDebug>
  6. class MyRun : public QRunnable {
  7. public:
  8. void run() {
  9. int i=3;
  10. while(i) {
  11. i--;
  12. qDebug()<<"thread start:"<<QThread::currentThreadId();
  13. QThread::msleep(500);
  14. }
  15. }
  16. };
  17. int main(int argc, char *argv[]) {
  18. QCoreApplication a(argc, argv);
  19. qDebug()<<"Main:"<<QThread::currentThreadId();
  20. QThreadPool pool;
  21. QThreadPool *global_pool = QThreadPool::globalInstance();
  22. MyRun *run=new MyRun;
  23. if(!run->autoDelete()) {
  24. qDebug()<<"QRunnable's autoDelete default value is not true";
  25. run->setAutoDelete(true);
  26. }
  27. pool.setMaxThreadCount(2);//修改了局部线程数量
  28. qDebug()<<"pool:"<<pool.maxThreadCount()<<pool.expiryTimeout()<<"\r\nglobal"<<global_pool->maxThreadCount();
  29. qDebug()<<pool.activeThreadCount()<<global_pool->activeThreadCount();
  30. pool.start(run);
  31. global_pool->start(new MyRun);
  32. qDebug()<<pool.activeThreadCount()<<global_pool->activeThreadCount();
  33. pool.waitForDone();
  34. global_pool->waitForDone();
  35. qDebug()<<pool.activeThreadCount()<<global_pool->activeThreadCount();
  36. return 0;
  37. }

结果

  1. Main: 0x30c4
  2. pool: 2 30000
  3. global 4
  4. 0 0
  5. 1 1
  6. thread start: 0x22d0
  7. thread start: 0xfe0
  8. thread start: 0x22d0
  9. thread start: 0xfe0
  10. thread start: 0x22d0
  11. thread start: 0xfe0
  12. 0 0

当建立局部线程池,修改其参数后仅供局部使用,不会影响全局线程池的。

转载请以链接形式标明本文标题和地址:Techie亮博客 » Qt多线程-QThreadPool线程池与QRunnable

Qt多线程-QThreadPool线程池与QRunnable相关推荐

  1. Qt多线程以及线程池

    目录 继承QThread类 简单使用 传递参数 QObject::MoveToThread()函数 QThreadPool线程池 多线程编程其实也不难,重要的是控制共享资源的修改,以及资源的使用权限控 ...

  2. Java的多线程和线程池的使用,你真的清楚了吗?

    Java的多线程和线程池的使用 多线程大大提高程序运行效率,我们在开发过程中经常会开启一个线程来执行一些费时的任务.开启一个线程有4种方式,在下面的文章我将详细的去讲解. 继承Thread 继承Thr ...

  3. 多线程之线程池-各个参数的含义- 阿里,美团,京东面试题目

    阿里的面试官问了个问题,如果corepollSize=10,MaxPollSize=20,如果来了25个线程 怎么办, 答案: 当一个任务通过execute(Runnable)方法欲添加到线程池时: ...

  4. Java多线程之线程池配置合理线程数

    Java多线程之线程池配置合理线程数 目录 代码查看公司服务器或阿里云是几核的 合理线程数配置之CPU密集型 合理线程数配置之IO密集型 1. 代码查看公司服务器或阿里云是几核的 要合理配置线程数首先 ...

  5. Java多线程之线程池的手写改造和拒绝策略

    Java多线程之线程池的手写改造和拒绝策略 目录 自定义线程池的使用 四种拒绝策略代码体现 1. 自定义线程池的使用 自定义线程池(拒绝策略默认AbortPolicy) public class My ...

  6. Java多线程之线程池7大参数、底层工作原理、拒绝策略详解

    Java多线程之线程池7大参数详解 目录 企业面试题 线程池7大参数源码 线程池7大参数详解 底层工作原理详解 线程池的4种拒绝策略理论简介 面试的坑:线程池实际中使用哪一个? 1. 企业面试题 蚂蚁 ...

  7. Java多线程之线程池详解

    Java多线程之线程池详解 目录: 线程池使用及优势 线程池3个常用方式 线程池7大参数深入介绍 线程池底层工作原理 1. 线程池使用及优势 线程池做的工作主要是控制运行的线程的数量,处理过程中将任务 ...

  8. pool python 传参数_Python-爬虫-多线程、线程池模拟(urllib、requests、UserAgent、超时等)...

    接着之前的MonkeyLei:Python-爬取页面内容(涉及urllib.requests.UserAgent.Json等) 继续练习下多线程,线程池模拟.. 我想这样: 1. 创建一个线程池,线程 ...

  9. java 多线程使用线程池_Java多线程:如何开始使用线程

    java 多线程使用线程池 什么是线程? (What is a Thread?) A thread is a lightweight process. Any process can have mul ...

最新文章

  1. closeable java_【转】java.io.Closeable接口
  2. 这些重大科技领域问题,听听专家怎么说
  3. ssh跳板登陆太麻烦,使用expect每次自动登录 利用expect 模拟键盘动作,在闲置时间之内模拟地给个键盘响应...
  4. 2014目标!!!!
  5. SHUoj 字符串进制转换
  6. C++Postfix Expression 后缀表达式的评估算法(附完整源码)
  7. 【C】——C项目中的菜单功能(源码)
  8. es Failed: 1: this action would add [2] total shards, but this cluster currently has [1001]/[1000]
  9. C#.NET高级面试题
  10. [每天一个知识点]20-Java语言-菱形运算符
  11. 小D课堂 - 新版本微服务springcloud+Docker教程_4-04 高级篇幅之服务间调用之负载均衡策略调整实战...
  12. R语言安装~R,Rstudio
  13. 比例电磁阀(零)液压知识
  14. 手把手教你解决PL2303驱动在Win10无法使用
  15. 关于 SQL Server Reporting Services 匿名登录的解决方案
  16. “赋能”企业,数加服装ERP智助企业乘风破浪
  17. PostgreSQL 生成空间热力图
  18. java计算机毕业设计校友社交系统源代码+数据库+系统+lw文档
  19. Android N App分屏模式完全解析(上)
  20. matlab的常量和变量运算符

热门文章

  1. 我编程很渣,但我就是喜欢编程,我该怎么做?放弃还是继续坚持?
  2. s3k3 破旧不堪的拐杖被扔出去几米远
  3. 把今天接到的任务都给搞定了
  4. 即时通讯的企业应用和个人应用的区别
  5. BOOT.INI文件的目的[微软提供]
  6. 第四节:5种数据类型在TypeScript中的运用
  7. 大白话,讲编程之《ES6系列连载》汇总,再也不用翻历史消息了
  8. 安卓升级鸿蒙,网友实测从安卓升级到鸿蒙2.0:可用内存和机身存储容量都增加了...
  9. 决策树算法学习笔记(提升篇)
  10. 这篇Cell里面的GSEA展示很不错!