Files
EJM_Display/Threads/MultiCoreManager.cpp
2025-10-20 22:28:37 +08:00

259 lines
8.5 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#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 << "个任务";
}
}
}