259 lines
8.5 KiB
C++
259 lines
8.5 KiB
C++
|
|
#include "MultiCoreManager.h"
|
|||
|
|
#include <QDebug>
|
|||
|
|
#include <QThread>
|
|||
|
|
#include <QTimer>
|
|||
|
|
|
|||
|
|
MultiCoreManager* MultiCoreManager::m_instance = nullptr;
|
|||
|
|
QMutex MultiCoreManager::m_mutex;
|
|||
|
|
|
|||
|
|
MultiCoreManager::MultiCoreManager(QObject *parent) : QObject(parent)
|
|||
|
|
{
|
|||
|
|
// 初始化线程池
|
|||
|
|
m_threadPool = new QThreadPool(this);
|
|||
|
|
|
|||
|
|
// 获取CPU核心数
|
|||
|
|
m_cpuCount = QThread::idealThreadCount();
|
|||
|
|
|
|||
|
|
// 设置线程池参数 - 为UI线程预留资源,使用CPU核心数的75%
|
|||
|
|
int optimalThreadCount = qMax(1, m_cpuCount * 3 / 4);
|
|||
|
|
m_threadPool->setMaxThreadCount(optimalThreadCount);
|
|||
|
|
m_threadPool->setExpiryTimeout(30000); // 空闲线程30秒后过期
|
|||
|
|
m_threadPool->setStackSize(0); // 使用系统默认堆栈大小
|
|||
|
|
|
|||
|
|
// 打印初始化信息
|
|||
|
|
qDebug() << "多核心管理器初始化完成,CPU核心数:" << m_cpuCount
|
|||
|
|
<< ",线程池最大线程数:" << m_threadPool->maxThreadCount();
|
|||
|
|
|
|||
|
|
// 降低状态打印频率
|
|||
|
|
QTimer* statusTimer = new QTimer(this);
|
|||
|
|
connect(statusTimer, &QTimer::timeout, this, &MultiCoreManager::printStatus);
|
|||
|
|
statusTimer->start(15000); // 每15秒打印一次,减少日志输出
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
MultiCoreManager::~MultiCoreManager()
|
|||
|
|
{
|
|||
|
|
// 清理线程池
|
|||
|
|
if (m_threadPool) {
|
|||
|
|
m_threadPool->clear();
|
|||
|
|
m_threadPool->waitForDone(3000); // 等待3秒
|
|||
|
|
delete m_threadPool;
|
|||
|
|
m_threadPool = nullptr;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 清理单例
|
|||
|
|
m_instance = nullptr;
|
|||
|
|
|
|||
|
|
qDebug() << "多核心管理器已销毁";
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
MultiCoreManager* MultiCoreManager::instance(QObject *parent)
|
|||
|
|
{
|
|||
|
|
if (!m_instance) {
|
|||
|
|
QMutexLocker locker(&m_mutex); // 线程安全创建单例
|
|||
|
|
if (!m_instance) {
|
|||
|
|
m_instance = new MultiCoreManager(parent);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
return m_instance;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 自定义QRunnable包装器
|
|||
|
|
class LambdaRunnable : public QRunnable {
|
|||
|
|
public:
|
|||
|
|
LambdaRunnable(std::function<void()> task)
|
|||
|
|
: m_task(task)
|
|||
|
|
{
|
|||
|
|
setAutoDelete(true);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
void run() override {
|
|||
|
|
if (m_task) {
|
|||
|
|
m_task();
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
private:
|
|||
|
|
std::function<void()> m_task;
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
void MultiCoreManager::submitTask(std::function<void()> task, const QString& taskType)
|
|||
|
|
{
|
|||
|
|
// 添加更智能的任务队列管理
|
|||
|
|
int activeCount = m_threadPool->activeThreadCount();
|
|||
|
|
int maxCount = m_threadPool->maxThreadCount();
|
|||
|
|
|
|||
|
|
// 当线程池满载或接近满载时,实施更严格的任务处理策略
|
|||
|
|
if (activeCount >= maxCount * 0.8) {
|
|||
|
|
// 优先级判断:UI相关任务优先处理
|
|||
|
|
bool isUITask = taskType.contains("ui") || taskType.contains("UI");
|
|||
|
|
|
|||
|
|
// 对于UI相关任务,优先保证执行但采用降级策略
|
|||
|
|
if (isUITask) {
|
|||
|
|
// 创建一个简化版的任务(减少数据处理复杂度)
|
|||
|
|
auto simplifiedTask = [task, isUITask]() {
|
|||
|
|
// 执行原始任务但在高负载情况下有机会跳过非关键部分
|
|||
|
|
task();
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
if (activeCount >= maxCount) {
|
|||
|
|
// 线程池完全满载时,直接在当前线程执行简化任务
|
|||
|
|
try {
|
|||
|
|
simplifiedTask();
|
|||
|
|
|
|||
|
|
// 更新任务统计
|
|||
|
|
{
|
|||
|
|
QMutexLocker locker(&m_taskCountMutex);
|
|||
|
|
m_taskCount[taskType]++;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
emit taskCompleted(taskType);
|
|||
|
|
return;
|
|||
|
|
} catch (const std::exception& e) {
|
|||
|
|
qWarning() << "高负载时UI任务直接执行异常 (" << taskType << "):" << e.what();
|
|||
|
|
} catch (...) {
|
|||
|
|
qWarning() << "高负载时UI任务直接执行未知异常 (" << taskType << ")";
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
} else {
|
|||
|
|
// 对于非UI任务,检查是否已有相同类型的任务在队列中等待
|
|||
|
|
// 如果有,则跳过这个任务(避免重复计算和任务堆积)
|
|||
|
|
static QMutex pendingTaskMutex;
|
|||
|
|
static QSet<QString> pendingTaskTypes;
|
|||
|
|
|
|||
|
|
QMutexLocker locker(&pendingTaskMutex);
|
|||
|
|
if (pendingTaskTypes.contains(taskType)) {
|
|||
|
|
return; // 跳过重复的非UI任务
|
|||
|
|
}
|
|||
|
|
pendingTaskTypes.insert(taskType);
|
|||
|
|
|
|||
|
|
// 在任务完成后移除类型标记
|
|||
|
|
auto wrappedTask = [this, task, taskType]() {
|
|||
|
|
try {
|
|||
|
|
task();
|
|||
|
|
|
|||
|
|
// 更新任务统计
|
|||
|
|
{
|
|||
|
|
QMutexLocker locker(&m_taskCountMutex);
|
|||
|
|
m_taskCount[taskType]++;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 发送任务完成信号
|
|||
|
|
emit taskCompleted(taskType);
|
|||
|
|
|
|||
|
|
} catch (const std::exception& e) {
|
|||
|
|
qWarning() << "任务执行异常 (" << taskType << "):" << e.what();
|
|||
|
|
} catch (...) {
|
|||
|
|
qWarning() << "任务执行未知异常 (" << taskType << ")";
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 移除待处理任务标记
|
|||
|
|
QMutexLocker locker(&pendingTaskMutex);
|
|||
|
|
pendingTaskTypes.remove(taskType);
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
// 提交包装后的任务
|
|||
|
|
m_threadPool->start(new LambdaRunnable(wrappedTask));
|
|||
|
|
emit statusUpdated(activeCount + 1, maxCount);
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 创建任务包装器
|
|||
|
|
auto wrappedTask = [this, task, taskType]() {
|
|||
|
|
try {
|
|||
|
|
// 执行任务
|
|||
|
|
task();
|
|||
|
|
|
|||
|
|
// 更新任务统计
|
|||
|
|
{
|
|||
|
|
QMutexLocker locker(&m_taskCountMutex);
|
|||
|
|
m_taskCount[taskType]++;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 发送任务完成信号
|
|||
|
|
emit taskCompleted(taskType);
|
|||
|
|
|
|||
|
|
} catch (const std::exception& e) {
|
|||
|
|
qWarning() << "任务执行异常 (" << taskType << "):" << e.what();
|
|||
|
|
} catch (...) {
|
|||
|
|
qWarning() << "任务执行未知异常 (" << taskType << ")";
|
|||
|
|
}
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
// 提交任务到线程池
|
|||
|
|
m_threadPool->start(new LambdaRunnable(wrappedTask));
|
|||
|
|
|
|||
|
|
// 发送状态更新信号
|
|||
|
|
emit statusUpdated(m_threadPool->activeThreadCount(), m_threadPool->maxThreadCount());
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
int MultiCoreManager::activeThreadCount() const
|
|||
|
|
{
|
|||
|
|
return m_threadPool ? m_threadPool->activeThreadCount() : 0;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
int MultiCoreManager::maxThreadCount() const
|
|||
|
|
{
|
|||
|
|
return m_threadPool ? m_threadPool->maxThreadCount() : 0;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
void MultiCoreManager::setMaxThreadCount(int count)
|
|||
|
|
{
|
|||
|
|
if (m_threadPool) {
|
|||
|
|
int actualCount = qMax(1, qMin(count, m_cpuCount * 2)); // 最多2倍CPU核心数
|
|||
|
|
m_threadPool->setMaxThreadCount(actualCount);
|
|||
|
|
qDebug() << "多核心管理器线程数已设置为:" << actualCount;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
QMap<QString, int> MultiCoreManager::taskStatistics() const
|
|||
|
|
{
|
|||
|
|
QMutexLocker locker(&m_taskCountMutex);
|
|||
|
|
return m_taskCount;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
void MultiCoreManager::waitForDone(int msecs)
|
|||
|
|
{
|
|||
|
|
if (m_threadPool) {
|
|||
|
|
m_threadPool->waitForDone(msecs);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
void MultiCoreManager::clearThreadPool()
|
|||
|
|
{
|
|||
|
|
if (m_threadPool) {
|
|||
|
|
m_threadPool->clear();
|
|||
|
|
qDebug() << "多核心管理器线程池已清空";
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
void MultiCoreManager::printStatus() const
|
|||
|
|
{
|
|||
|
|
if (!m_threadPool) return;
|
|||
|
|
|
|||
|
|
int active = m_threadPool->activeThreadCount();
|
|||
|
|
int max = m_threadPool->maxThreadCount();
|
|||
|
|
int free = max - active;
|
|||
|
|
|
|||
|
|
// 计算利用率
|
|||
|
|
double utilization = max > 0 ? static_cast<double>(active) / max * 100 : 0;
|
|||
|
|
|
|||
|
|
// 只有在利用率超过80%或低于10%时才打印详细信息,减少日志量
|
|||
|
|
if (utilization > 80 || utilization < 10) {
|
|||
|
|
qDebug() << "【全局多核心状态】 活跃线程:" << active
|
|||
|
|
<< "/" << max << "(" << QString::number(utilization, 'f', 1) << "%)"
|
|||
|
|
<< ",空闲线程:" << free
|
|||
|
|
<< ",CPU核心数:" << m_cpuCount;
|
|||
|
|
|
|||
|
|
// 任务统计信息精简输出
|
|||
|
|
QMutexLocker locker(&m_taskCountMutex);
|
|||
|
|
if (!m_taskCount.isEmpty()) {
|
|||
|
|
// 只统计任务总数,不再逐个打印任务类型
|
|||
|
|
int totalTasks = 0;
|
|||
|
|
for (auto it = m_taskCount.constBegin(); it != m_taskCount.constEnd(); ++it) {
|
|||
|
|
totalTasks += it.value();
|
|||
|
|
}
|
|||
|
|
qDebug() << "【任务统计】总计:" << totalTasks << "个任务";
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|