目标
本文章基于QT5 c++11的多线程机制,尝试构造一种能够批量新建、关联管理、状态反馈、有序退出的服务模式
类设计
1、多线程服务类ThreadService,承担线程外部对接操作;调用线程初始化操作;装载线程所需数据;调用线程销毁操作;接收线程信号并新建、销毁线程管理队列功能,是外部功能的对接接口和内部线程组的管理模块。
2、线程功能基类,负责实现线程的基础功能,如启动线程运行返回线程开始信号、结束线程销毁装载数据并返回结束信号、记录线程id和线程组关联关系(比如一个操作的多个关联线程称为一个线程组)。
3、线程功能继承类,实现各线程专职功能,继承于线程功能基类。由于QT5推荐采用QObject moveToThread的方式建立多线程,因此,我们的线程功能类本质上是QObject,不用QThread。
多线程服务类ThreadService
ThreadService管理线程的创建与销毁,通过addThread方法将线程功能对象move到新建线程中,就可以使线程功能对象的所有函数运行于子线程中。
线程开始运行与结束运行时将发出信号,建立线程后,将线程基本信息保存在QList中,之后的所有对线程的操作都通过链表找到目标线程指针,进行操作。线程完成信号到达时,会把线程基本信息从列表中清除,这样线程就被释放掉了。
关闭ThreadService服务时,也会将列表中的所有线程依次关掉,并等待其完成(防止线程跑完以后回调出现空指针)后再完成析构。
/*threadservice.h*/
#ifndef THREADSERVICE_H
#define THREADSERVICE_H
#include <QThread>
#include <QList>
#include <QMutex>
#include "basicservice/basicservice.h"
#include "thread/basicthread/basicthread.h"
#define APPAPI_ID int //APPAPI_ID 是我们串联起某个操作的全部线程的关联id
class ThreadService : public BasicService{
Q_OBJECT
private:
typedef struct{
int threadID = -1;
APPAPI_ID groupID = -1;
QString threadName = "";
APPSAPIContext context;
BasicThread * threadObj = nullptr;
QThread * thread = nullptr;
} ThreadItem;
public:
~ThreadService();
static ThreadService * getInstance(QObject * parent = nullptr);
void addThread(APPAPI_ID groupID,QString threadName,BasicThread * threadObj);//新建线程方法
void removeGroup(APPAPI_ID groupID);//停止线程组方法
BasicThread * checkExist(QString threadName);//判断线程是否存在方法
void addListen(void * sender,void(*afterThreadChange)(void *,int,APPSAPIThread*));
APPSAPIThread * getThreadList(int & num);
QList<ThreadItem> getThreadList();
private:
static ThreadService * instance;
int id = 0;
QList<ThreadItem>threadList;
void * senderObj = nullptr;
void(*afterThreadChange)(void *,int,APPSAPIThread*) = nullptr;
QMutex mutex;
private:
ThreadService(QObject * parent = nullptr);
void changeCallback();
private slots:
void threadEnd();
};
#endif // THREADSERVICE_H
/*threadservice.cpp*/
#include "threadservice.h"
ThreadService::ThreadService(QObject *parent):BasicService(parent){
if(instance==nullptr){
instance = this;
}
}
ThreadService::~