/
savushkin
/
CubeTaskManager
Обзор
Документация
Войти
/
savushkin
/
CubeTaskManager
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
CI/CD
Аналитика
Безопасность
master
cube_tm2/task_scheduler.cpp
452 строки
14 KB
Alexander Savushkin
feat: cube_tm_2 - 2025-10-23 17:58:06
23 окт 2025, 17:58
23 окт 2025, 17:58
02548f3
Код
Авторство
О чём код?
#include "task_scheduler.h" #include <iostream> #include <random> TaskScheduler::TaskScheduler(int max_tasks_count) : next_task_id(1), running(false), max_tasks(max_tasks_count), tasks_threshold(max_tasks_count * 2 / 3), // Порог = 2/3 от максимального количества random_engine(std::chrono::system_clock::now().time_since_epoch().count()) { std::srand(std::time(0)); initializeScheduler(); // Инициализация вероятностей выполнения execution_probabilities.resize(PRIORITY_GROUPS, 1.0); calculateExecutionProbabilities(); } TaskScheduler::~TaskScheduler() { stopExecution(); } void TaskScheduler::initializeScheduler() { // Создаем начальную структуру с пустыми узлами auto ***nodes = new std::shared_ptr<ThreeDNode<Task>> **[PRIORITY_GROUPS]; for (int x = 0; x < PRIORITY_GROUPS; x++) { nodes[x] = new std::shared_ptr<ThreeDNode<Task>> *[TASK_TYPES]; for (int y = 0; y < TASK_TYPES; y++) { nodes[x][y] = new std::shared_ptr<ThreeDNode<Task>>[1]; nodes[x][y][0] = nullptr; } } origin = nullptr; // Очистка временного массива for (int x = 0; x < PRIORITY_GROUPS; x++) { for (int y = 0; y < TASK_TYPES; y++) { delete[] nodes[x][y]; } delete[] nodes[x]; } delete[] nodes; } int TaskScheduler::getXCoord(int priority_group) { return std::max(0, std::min(PRIORITY_GROUPS - 1, priority_group)); } int TaskScheduler::getYCoord(TaskType type) { return static_cast<int>(type); } void TaskScheduler::addTask(std::shared_ptr<Task> task) { if (getTaskCount() >= max_tasks) { std::cout << "⚠️ Достигнут лимит задач (" << max_tasks << "). Задача '" << task->name << "' не добавлена." << std::endl; return; } auto new_node = std::make_shared<ThreeDNode<Task>>(task); int priority_group = task->getPriorityGroup(); int x = getXCoord(priority_group); int y = getYCoord(task->type); if (!origin) { origin = new_node; } else { auto last_node = findLastInZChain(x, y); if (last_node) { last_node->next_z = new_node; } else { auto xy_node = findXYNode(x, y); if (xy_node) { xy_node->next_z = new_node; } else { createNewChain(x, y, new_node); } } } std::cout << "✅ Задача добавлена в диспетчер: " << task->name << " (ID: " << task->task_id << ", Приоритет: " << task->getPriorityPercent() << "%)" << std::endl; // Пересчитываем вероятности выполнения calculateExecutionProbabilities(); updateSkipFlagsBasedOnLoad(); } bool TaskScheduler::removeTask(int task_id) { if (!origin) return false; for (int x = 0; x < PRIORITY_GROUPS; x++) { for (int y = 0; y < TASK_TYPES; y++) { auto current = findXYNode(x, y); std::shared_ptr<ThreeDNode<Task>> prev = nullptr; while (current) { if (current->data->task_id == task_id) { if (prev) { prev->next_z = current->next_z; } else { updateFirstInZChain(x, y, current->next_z); } std::cout << "🗑️ Задача удалена: " << current->data->name << " (ID: " << task_id << ")" << std::endl; // Пересчитываем вероятности выполнения calculateExecutionProbabilities(); updateSkipFlagsBasedOnLoad(); return true; } prev = current; current = current->next_z; } } } std::cout << "❌ Задача с ID " << task_id << " не найдена" << std::endl; return false; } void TaskScheduler::optimizeTasks() { std::cout << "🔧 Оптимизация задач..." << std::endl; // Пересчет вероятностей выполнения calculateExecutionProbabilities(); updateSkipFlagsBasedOnLoad(); std::cout << "✅ Оптимизация завершена" << std::endl; } void TaskScheduler::runTasksByType(TaskType type) { std::cout << "\n=== Запуск задач типа " << static_cast<int>(type) << " ===" << std::endl; for (int x = 0; x < PRIORITY_GROUPS; x++) { auto tasks = getTasksByPriorityGroupAndType(x, type); for (const auto &task : tasks) { if (task->state != TaskState::TERMINATED && shouldExecuteTask(task)) { task->execute(); } } } } void TaskScheduler::suspendTasksByType(TaskType type) { std::cout << "\n=== Остановка задач типа " << static_cast<int>(type) << " ===" << std::endl; for (int x = 0; x < PRIORITY_GROUPS; x++) { auto tasks = getTasksByPriorityGroupAndType(x, type); for (const auto &task : tasks) { if (task->state == TaskState::RUNNING || task->state == TaskState::READY) { task->suspend(); } } } } bool TaskScheduler::changeTaskPriority(int task_id, int new_priority_percent) { std::shared_ptr<Task> task_to_move = nullptr; TaskType original_type; for (int x = 0; x < PRIORITY_GROUPS && !task_to_move; x++) { for (int y = 0; y < TASK_TYPES && !task_to_move; y++) { auto current = findXYNode(x, y); while (current && !task_to_move) { if (current->data->task_id == task_id) { task_to_move = current->data; original_type = current->data->type; break; } current = current->next_z; } } } if (!task_to_move) { std::cout << "❌ Задача с ID " << task_id << " не найдена" << std::endl; return false; } removeTask(task_id); task_to_move->setPriorityPercent(new_priority_percent); addTask(task_to_move); std::cout << "📊 Приоритет задачи " << task_to_move->name << " изменен на " << new_priority_percent << "%" << std::endl; return true; } void TaskScheduler::displayAllTasks() { std::cout << "\n=== ВСЕ ЗАДАЧИ (лимит: " << max_tasks << ") ===" << std::endl; bool has_tasks = false; int total_tasks = 0; for (int x = PRIORITY_GROUPS - 1; x >= 0; x--) { // Выводим от высоких к низким приоритетам for (int y = 0; y < TASK_TYPES; y++) { auto current = findXYNode(x, y); int count = 0; while (current) { if (count == 0) { std::cout << "\n--- ГРУППА ПРИОРИТЕТА " << x << " (" << (x * 10) << "-" << ((x + 1) * 10) << "%) | "; switch (static_cast<TaskType>(y)) { case TaskType::SYSTEM: std::cout << "СИСТЕМНЫЕ"; break; case TaskType::USER: std::cout << "ПОЛЬЗОВАТЕЛЬСКИЕ"; break; case TaskType::BACKGROUND: std::cout << "ФОНОВЫЕ"; break; } std::cout << " | Вероятность выполнения: " << (execution_probabilities[x] * 100) << "% ---" << std::endl; } auto task = current->data; std::cout << " ID: " << task->task_id << " | Имя: " << task->name; if (task->icon_data && task->icon_size > 0) { std::cout << " 🖼️"; } if (task->skip_execution) { std::cout << " ⏭️"; } std::cout << " | Приоритет: " << task->getPriorityPercent() << "%" << " | Состояние: "; switch (task->state) { case TaskState::READY: std::cout << "Готово"; break; case TaskState::RUNNING: std::cout << "Выполняется"; break; case TaskState::SUSPENDED: std::cout << "Приостановлено"; break; case TaskState::TERMINATED: std::cout << "Завершено"; break; } std::cout << " | CPU: " << task->cpu_usage << "%" << " | Память: " << task->memory_usage << "KB" << " | Выполнений: " << task->execution_count << std::endl; count++; total_tasks++; has_tasks = true; current = current->next_z; } } } if (!has_tasks) { std::cout << "📭 Нет задач в диспетчере" << std::endl; } else { std::cout << "\n📊 Всего задач: " << total_tasks << "/" << max_tasks << std::endl; } } // Остальные методы остаются аналогичными, но с адаптацией под процентную систему... // [Здесь должны быть реализации остальных методов из предыдущего кода, адаптированные под новую архитектуру] // Расчет вероятностей выполнения на основе загрузки системы void TaskScheduler::calculateExecutionProbabilities() { int total_tasks = getTaskCount(); double load_factor = static_cast<double>(total_tasks) / max_tasks; std::cout << "📈 Расчет вероятностей выполнения. Загрузка: " << (load_factor * 100) << "%" << std::endl; for (int group = 0; group < PRIORITY_GROUPS; group++) { double base_probability = 1.0 - (group * 0.1); // Базовая вероятность от 100% до 10% if (load_factor > 0.8) { // Высокая загрузка (>80%) execution_probabilities[group] = base_probability * 0.5; } else if (load_factor > 0.5) { // Средняя загрузка (>50%) execution_probabilities[group] = base_probability * 0.8; } else { // Низкая загрузка execution_probabilities[group] = base_probability; } // Группа 0 (0-10% приоритет) может быть полностью отключена при высокой нагрузке if (group == 0 && load_factor > 0.9) { execution_probabilities[group] = 0.0; } std::cout << " Группа " << group << ": " << (execution_probabilities[group] * 100) << "%" << std::endl; } } // Определение, должна ли задача быть выполнена bool TaskScheduler::shouldExecuteTask(const std::shared_ptr<Task> &task) const { int group = task->getPriorityGroup(); std::bernoulli_distribution dist(execution_probabilities[group]); return dist(random_engine); } // Обновление флагов пропуска на основе загрузки void TaskScheduler::updateSkipFlagsBasedOnLoad() { int total_tasks = getTaskCount(); for (int x = 0; x < PRIORITY_GROUPS; x++) { for (int y = 0; y < TASK_TYPES; y++) { auto current = findXYNode(x, y); while (current) { // Для низкоприоритетных задач устанавливаем флаг пропуска // на основе вероятности выполнения current->data->setSkipExecution(!shouldExecuteTask(current->data)); current = current->next_z; } } } } void TaskScheduler::startExecution() { if (running) return; running = true; execution_thread = std::thread(&TaskScheduler::executionLoop, this); std::cout << "🔄 Запуск циклического выполнения задач..." << std::endl; } void TaskScheduler::executionLoop() { int cycle = 0; while (running) { std::this_thread::sleep_for(std::chrono::seconds(3)); cycle++; std::cout << "\n🔄 Цикл выполнения #" << cycle << std::endl; std::cout << "====================" << std::endl; // Выполняем задачи от высоких к низким приоритетам for (int x = PRIORITY_GROUPS - 1; x >= 0 && running; x--) { for (int y = 0; y < TASK_TYPES && running; y++) { auto current = findXYNode(x, y); while (current && running) { auto task = current->data; if ((task->state == TaskState::READY || task->state == TaskState::RUNNING) && shouldExecuteTask(task)) { task->execute(); } current = current->next_z; } } } // Периодическая оптимизация (каждые 2 цикла) if (cycle % 2 == 0) { calculateExecutionProbabilities(); updateSkipFlagsBasedOnLoad(); } // Вывод состояния каждые 4 цикла if (cycle % 4 == 0) { displayAllTasks(); } } } // [Реализации остальных методов...]