C++11消息队列 + Qt线程池 + QRunnable执行任务简单模型
标签:代码 front http cte ble 指针 volatile volatil 字符
1、模板类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
#include
#include string>
#include 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
#include
Run::Run(const MyString &myString)
{
this->myString = myString;
//this->setAutoDelete(true);//默认就是true
}
void Run::run()
{
//std::cout myString.valueStr
qDebug() "value:" "thread:" QThread::currentThreadId();
QThread::msleep(100);
}
说明:不使用cout打印是因为,cout打印不是原子操作,可能多个字符串被杂糅在一起打印;qDebug不会,应该底层加了锁
main.cpp
#include
#include "run.h"
#include
#include
#include
#include using namespace std;
queue 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(20);
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(10);
}
}
}
cout "end main,list size:" endl;
return a.exec();
}
void makeListThread()
{
string a;
MyString tempMyString;
for(int i=0;i10000;i++)
{
QThread::msleep(0);
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执行任务简单模型
标签:代码 front http cte ble 指针 volatile volatil 字符
原文地址:https://www.cnblogs.com/judes/p/11013450.html
评论