C++11消息队列 + Qt线程池 + QRunnable执行任务简单模型
1、模板类queue,包含头文件<queue>中,是一个FIFO队列。
- queue.push():在队列尾巴增加数据
- queue.pop():移除队列头部数据
- queue.font():获取队列头部数据的引用
...
2、Qt库的线程池,QThreadPool
- QThreadPool.setMaxThreadCount():设置线程池最大线程数
- QThreadPool.start(new QRunnable(..)):开启线程池调用QRunnable
3、QRunnable执行任务
- void run();//重写虚函数,在里面消费任务队列
- setAutoDelete(true)//默认就是true,消费结束自动回收内存
4、代码
run.h
- #ifndef RUN_H
- #define RUN_H
- #include <QObject>
- #include <QRunnable>
- #include <string>
- #include <iostream>
- struct MyString
- {
- std::string valueStr;
- };
- class Run : public QObject , public QRunnable
- {
- Q_OBJECT
- public:
- Run() = default;
- Run(const MyString& myString);
- protected:
- ~Run() = default;
- void run();
- signals:
- public slots:
- private:
- MyString myString;
- };
- #endif // RUN_H
- 说明:MyString结构体代替实际项目中的任务,Run接口的run纯虚函数用来消费分配来的MyString
- run.cpp
- #include "run.h"
- #include <QThread>
- #include <QDebug>
- Run::Run(const MyString &myString)
- {
- this->myString = myString;
- //this->setAutoDelete(true);//默认就是true
- }
- void Run::run()
- {
- //std::cout << "value:" << this->myString.valueStr <<";调用线程ID为:" << QThread::currentThread() << std::endl;
- qDebug() << "value:" << QString::fromStdString(myString.valueStr) << "thread:" << QThread::currentThreadId();
- QThread::msleep();
- }
说明:不使用cout打印是因为,cout打印不是原子操作,可能多个字符串被杂糅在一起打印;qDebug不会,应该底层加了锁
main.cpp
- #include <QCoreApplication>
- #include "run.h"
- #include <queue>
- #include <mutex>
- #include <QThreadPool>
- #include <thread>
- using namespace std;
- queue<MyString> myList;
- mutex myMutex;
- volatile bool addThreadIsEnd = false;
- void makeListThread();
- int main(int argc, char *argv[])
- {
- QCoreApplication a(argc, argv);
- cout << "begin main" << endl;
- thread addThread(makeListThread);
- addThread.detach();
- cout << "begin addThread" << endl;
- QThreadPool tp;
- tp.setMaxThreadCount();
- cout << "begin threadPool" << endl;
- while(true)
- {
- if(!myList.empty())
- {
- MyString tempMyString = myList.front();
- tp.start(new Run(tempMyString));
- myMutex.lock();
- myList.pop();
- myMutex.unlock();
- }
- else
- {
- if(addThreadIsEnd)
- {
- break;
- }
- else
- {
- QThread::msleep();
- }
- }
- }
- cout << "end main,list size:" << myList.size() << endl;
- return a.exec();
- }
- void makeListThread()
- {
- string a;
- MyString tempMyString;
- for(int i=;i<;i++)
- {
- QThread::msleep();
- a = to_string(i);
- tempMyString.valueStr = a;
- myMutex.lock();
- myList.push(tempMyString);
- myMutex.unlock();
- }
- addThreadIsEnd = true;
- cout << "end addThread" << endl;
- }
- 5、模型
6、其他说明
6.1、假设线程池大小有n个,那么这n个线程在线程池初始化的时候就已经定了,即n个线程id是恒定的,队列永远由这n个线程消费
6.2、std::queue非线程安全,同时往队列加任务、取任务可能会触发线程安全问题;同时删除头任务、访问头任务也可能会触发线程安全问题,需要加线程锁
6.3、tp.start(new Run(tempMyString));这里new了一个没有指针指向的Runnable对象,在哪里回收的呢?Run.setAutoDelete(true)自动回收
C++11消息队列 + Qt线程池 + QRunnable执行任务简单模型的更多相关文章
- c++之初级的消息队列及线程池模型
1.最近项目不是很忙,结合之前看的一些开源代码(skynet及其他github代码)及项目代码,抽空写了一个简单的任务队列当做练习. 2.介绍: 1)全局队列中锁的使用:多线程下,全局队列需要加锁,本 ...
- 自定义ThreadPoolExecutor带Queue缓冲队列的线程池 + JMeter模拟并发下单请求
.原文:https://blog.csdn.net/u011677147/article/details/80271174 拓展: https://github.com/jwpttcg66/GameT ...
- java并发编程(四) 线程池 & 任务执行、终止源码分析
参考文档 线程池任务执行全过程:https://blog.csdn.net/wojiaolinaaa/article/details/51345789 线程池中断:https://www.cnblog ...
- 重新想象 Windows 8 Store Apps (42) - 多线程之线程池: 延迟执行, 周期执行, 在线程池中找一个线程去执行指定的方法
[源码下载] 重新想象 Windows 8 Store Apps (42) - 多线程之线程池: 延迟执行, 周期执行, 在线程池中找一个线程去执行指定的方法 作者:webabcd 介绍重新想象 Wi ...
- C# -- 使用线程池 ThreadPool 执行多线程任务
C# -- 使用线程池 ThreadPool 执行多线程任务 1. 使用线程池 class Program { static void Main(string[] args) { WaitCallba ...
- ForkJoinPool线程池--分支执行
import java.util.ArrayList; import java.util.concurrent.ExecutionException; import java.util.concurr ...
- Qt 线程池QThreadPool类、QRunnable类
QThreadPool类 用来管理 QThreads.此类中的所有函数都是线程安全的. 主要属性: 1.activeThreadCount: 此属性表示线程池中的活动线程数,通过activeThrea ...
- QT 线程池 + TCP 小试(一)线程池的简单实现
*免分资源链接点击打开链接http://download.csdn.net/detail/goldenhawking/4492378 很久以前做过ACE + MFC/QT 的中轻量级线程池应用,大概就 ...
- Qt线程池
说明 Qt中可以有多种使用线程的方式: 继承 QThread,重写 run() 接口: 使用 moveToThread() 方法将 QObject 子类移至线程中,内部的所有使用信号槽的槽函数均在线程 ...
随机推荐
- 如何制作一个Arduino温度数据记录仪
在本项目中,我们将使用Arduino开发板制作一个温度数据记录仪,该设备从温度传感器LM35获取温度值,并从DS3231实时时钟模块获取时间.然后我们将使用mini SD卡模块将这些值存储在SD卡文件 ...
- 使用C#应用程序与Arduino开发板进行通信
在本文中,我们将一个Arduino Pro Mini开发板连接到PC,并且使用C# Windows应用程序与其进行通信. 将硬件连接到PC是非常有利的,不仅是因为你可以发送命令以及监控状态,还可以实时 ...
- 解密Redis持久化【翻译】
本文来自Redis的作者,他在论坛看到大家对Redis持久化误解较大,所以写此文章论述持久化 写操作的流程 首先我们来看一下数据库在进行写操作时到底做了哪些事,主要有下面五个过程. 客户端向服务端发送 ...
- MyEclipse修改运行内存
修改 myeclipse.ini -vmargs -Xmx1768m -XX:MaxPermSize=1320m -XX:ReservedCodeCacheSize=64m -Dosgi.nls.w ...
- Socket实现client和server端通信(Java)(转)
转自: https://blog.csdn.net/yayun0516/article/details/50819147 https://www.jianshu.com/p/2d4f223f1462 ...
- ZZNU - OJ - 2080 : A+B or A-B【暴力枚举】
2080 : A+B or A-B(点击左侧标题进入zznu原题页面) 时间限制:1 Sec 内存限制:0 MiB提交:8 答案正确:3 提交 状态 讨论区 题目描述 Give you three s ...
- 2019-2020-1 20199312《Linux内核原理与分析》第一周作业
实验一:linux系统简介 Linux 本身只是操作系统的内核.内核是使其它程序能够运行的基础.它实现了多任务和硬件管理,用户或者系统管理员交互运行的所有程序实际上都运行在内核之上.其中有些程序是必需 ...
- 1~n中数字0~9出现的次数
题意:rt 分析: 当然不可能去遍历,应该寻找统计的方法. 如计算 78501 中 "5" 出现的次数. 我们可以枚举“5”出现的位置, 如当“5”位于倒数第2位时,写成 xxx5 ...
- 编写一个求圆面积的C语言程序
#include<stdio.h> //文件包含//#define PI 3.14 //宏定义//void main() { float r,s; scanf( ...
- [React + GraphQL] Use useLazyQuery to manually execute a query with Apollo React Hooks
When using useQuery from Apollo React Hooks, the request will be sent automatically after the compon ...