From b5c08ccd75fa805bd3918b29f27fc1898b406931 Mon Sep 17 00:00:00 2001 From: nanako <469449812@qq.com> Date: Tue, 4 Nov 2025 01:26:44 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BC=98=E5=8C=96=E4=BB=A3=E7=A0=81=E6=A0=BC?= =?UTF-8?q?=E5=BC=8F=EF=BC=8C=E8=B0=83=E6=95=B4=E6=B3=A8=E9=87=8A=E5=92=8C?= =?UTF-8?q?=E7=A9=BA=E8=A1=8C=EF=BC=8C=E5=A2=9E=E5=BC=BA=E5=8F=AF=E8=AF=BB?= =?UTF-8?q?=E6=80=A7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/engine/main.cpp | 48 +- src/process_manager/process_manager.cpp | 746 ++++++++-------- src/process_manager/process_manager.h | 292 ++++--- src/process_manager/process_monitor.cpp | 555 ++++++------ src/process_manager/process_monitor.h | 274 +++--- src/process_manager/process_types.h | 219 ++--- .../process_manager/test_process_manager.cpp | 820 +++++++++--------- 7 files changed, 1484 insertions(+), 1470 deletions(-) diff --git a/src/engine/main.cpp b/src/engine/main.cpp index 33732ce..ff62fc6 100644 --- a/src/engine/main.cpp +++ b/src/engine/main.cpp @@ -9,7 +9,7 @@ int main(int argc, char* argv[]) { std::cout << "=== Alicho Audio Backend Engine 启动 ===" << std::endl; - + // 初始化共享内存管理器 shared_memory_config shm_config{}; shm_config.segment_name = "AlichoBackendSharedMemory"; @@ -28,49 +28,52 @@ int main(int argc, char* argv[]) { // 设置进程管理器回调函数 alicho::process_manager& pm = alicho::process_manager::instance(); - + // 设置进程状态变化回调 pm.set_state_change_callback([](const alicho::process_info& info, alicho::process_state new_state) { std::cout << "[进程管理器] 进程 " << info.id << " (" << info.name << ")" - << " 状态变化: " << alicho::process_state_to_string(info.state) - << " -> " << alicho::process_state_to_string(new_state) << std::endl; + << " 状态变化: " << alicho::process_state_to_string(info.state) + << " -> " << alicho::process_state_to_string(new_state) << std::endl; }); // 设置进程资源使用回调 pm.set_resource_callback([](const alicho::process_info& info, const alicho::process_resource_usage& usage) { - if (usage.cpu_percent > 50.0) { // 只在CPU使用率较高时打印 + if (usage.cpu_percent > 50.0) { + // 只在CPU使用率较高时打印 std::cout << "[进程管理器] 进程 " << info.id << " (" << info.name << ")" - << " 资源使用: CPU " << usage.cpu_percent << "%, 内存 " - << usage.memory_usage_kb << "KB" << std::endl; + << " 资源使用: CPU " << usage.cpu_percent << "%, 内存 " + << usage.memory_usage_kb << "KB" << std::endl; } }); // 设置进程错误回调 - pm.set_error_callback([](const alicho::process_info& info, alicho::process_error error, const std::string& error_message) { + pm.set_error_callback([](const alicho::process_info& info, alicho::process_error error, + const std::string& error_message) { std::cout << "[进程管理器] 进程 " << info.id << " (" << info.name << ")" - << " 发生错误 [" << alicho::process_error_to_string(error) << "]: " - << error_message << std::endl; + << " 发生错误 [" << alicho::process_error_to_string(error) << "]: " + << error_message << std::endl; }); std::cout << "[引擎] 进程管理器回调设置完成" << std::endl; // 示例:启动沙箱进程(如果存在沙箱可执行文件) // 注意:这里假设沙箱可执行文件位于相对路径,实际使用时需要根据具体情况调整 - std::string sandbox_executable = "alicho_host_sandbox"; // 或者使用完整路径 - std::vector sandbox_args = {"--mode", "host"}; - + std::string sandbox_executable = "alicho_host_sandbox"; // 或者使用完整路径 + std::vector sandbox_args = {"--mode", "host"}; + std::cout << "[引擎] 尝试启动沙箱进程..." << std::endl; uint32_t sandbox_pid = pm.launch_process( - "host_sandbox", // 进程名称 - sandbox_executable, // 可执行文件路径 - sandbox_args, // 命令行参数 + "host_sandbox", // 进程名称 + sandbox_executable, // 可执行文件路径 + sandbox_args, // 命令行参数 alicho::sandbox_type::HOST, // 沙箱类型 - true // 启用监控 + true // 启用监控 ); if (sandbox_pid != 0) { std::cout << "[引擎] 沙箱进程启动成功,PID: " << sandbox_pid << std::endl; - } else { + } + else { std::cout << "[引擎] 沙箱进程启动失败,将继续运行引擎" << std::endl; } @@ -82,7 +85,7 @@ int main(int argc, char* argv[]) { while (running) { // 处理ZMQ消息 zmq_server::instance().recv(); - + // 检查进程状态(可选) if (sandbox_pid != 0 && pm.has_process(sandbox_pid)) { if (!pm.is_process_running(sandbox_pid)) { @@ -90,18 +93,19 @@ int main(int argc, char* argv[]) { sandbox_pid = 0; // 清除PID } } - + std::this_thread::sleep_for(std::chrono::milliseconds(10)); } // 清理资源 std::cout << "[引擎] 开始清理资源..." << std::endl; - + // 终止所有管理的进程 auto result = pm.terminate_all_processes(false, std::chrono::milliseconds(5000)); if (result == alicho::process_error::SUCCESS) { std::cout << "[引擎] 所有进程已正常终止" << std::endl; - } else { + } + else { std::cout << "[引擎] 进程终止时发生错误: " << alicho::process_error_to_string(result) << std::endl; } diff --git a/src/process_manager/process_manager.cpp b/src/process_manager/process_manager.cpp index d05e14d..9dfd996 100644 --- a/src/process_manager/process_manager.cpp +++ b/src/process_manager/process_manager.cpp @@ -9,10 +9,10 @@ // 平台特定头文件用于强制终止进程 #ifdef _WIN32 - #include +#include #else - #include - #include +#include +#include #endif #define PROCESS_MANAGER_LOG_MODULE "process_manager" @@ -23,394 +23,392 @@ #define log_module_error(module, ...) SPDLOG_LOGGER_ERROR(spdlog::default_logger(), "[{}] {}", module, fmt::format(__VA_ARGS__)) namespace alicho { + process_manager::process_manager() : next_process_id_(1) { + log_module_info(PROCESS_MANAGER_LOG_MODULE, "进程管理器初始化"); + } -process_manager::process_manager() : next_process_id_(1) { - log_module_info(PROCESS_MANAGER_LOG_MODULE, "进程管理器初始化"); -} + process_manager::~process_manager() { + // 终止所有进程 + terminate_all_processes(true); + log_module_info(PROCESS_MANAGER_LOG_MODULE, "进程管理器销毁"); + } -process_manager::~process_manager() { - // 终止所有进程 - terminate_all_processes(true); - log_module_info(PROCESS_MANAGER_LOG_MODULE, "进程管理器销毁"); -} + uint32_t process_manager::launch_process( + const std::string& name, + const std::string& executable_path, + const std::vector& arguments, + sandbox_type type, + bool monitor + ) { + std::lock_guard lock(manager_mutex_); + return launch_process_internal(name, executable_path, arguments, type, monitor); + } -uint32_t process_manager::launch_process( - const std::string& name, - const std::string& executable_path, - const std::vector& arguments, - sandbox_type type, - bool monitor -) { - std::lock_guard lock(manager_mutex_); - return launch_process_internal(name, executable_path, arguments, type, monitor); -} + uint32_t process_manager::launch_process_internal( + const std::string& name, + const std::string& executable_path, + const std::vector& arguments, + sandbox_type type, + bool monitor + ) { + try { + // 检查可执行文件是否存在 + if (!std::filesystem::exists(executable_path)) { + log_module_error(PROCESS_MANAGER_LOG_MODULE, "可执行文件不存在: {}", executable_path); + return 0; + } -uint32_t process_manager::launch_process_internal( - const std::string& name, - const std::string& executable_path, - const std::vector& arguments, - sandbox_type type, - bool monitor -) { - try { - // 检查可执行文件是否存在 - if (!std::filesystem::exists(executable_path)) { - log_module_error(PROCESS_MANAGER_LOG_MODULE, "可执行文件不存在: {}", executable_path); - return 0; - } + // 生成进程ID + uint32_t process_id = generate_process_id(); - // 生成进程ID - uint32_t process_id = generate_process_id(); - - // 创建进程信息对象 - auto process_info_ptr = std::make_unique( - process_id, name, executable_path, arguments, type); - - // 准备启动进程 - log_module_info(PROCESS_MANAGER_LOG_MODULE, "启动进程: 名称={}, 路径={}, ID={}", - name, executable_path, process_id); - - // 构建命令行参数字符串 - std::stringstream args_stream; - for (const auto& arg : arguments) { - args_stream << " " << arg; - } - - // 记录启动状态 - process_info_ptr->state = process_state::STARTING; - process_info_ptr->start_time = std::chrono::system_clock::now(); - - try { - // 使用Boost.Process启动子进程 (boost 1.89.0 API) - namespace bp = boost::process; - - // 创建子进程对象(boost 1.89.0正确语法:直接传递参数向量) - process_info_ptr->process = std::make_unique( - io_context_, - executable_path, - arguments, - bp::process_stdio{} - ); - - // 检查进程是否成功启动 - if (!process_info_ptr->process->running()) { - log_module_error(PROCESS_MANAGER_LOG_MODULE, "进程启动失败: {}", executable_path); - return 0; - } - - // 保持STARTING状态,让监控器检测后更新为RUNNING - // 这样可以触发状态变化回调 - // process_info_ptr->state = process_state::RUNNING; - - // 添加进程到管理列表 - processes_[process_id] = std::move(process_info_ptr); - - // 如果需要监控,则创建进程监控器 - if (monitor) { - create_process_monitor(*processes_[process_id]); - } - - log_module_info(PROCESS_MANAGER_LOG_MODULE, "进程启动成功: 名称={}, ID={}", name, process_id); - return process_id; - } - catch (const std::exception& e) { - log_module_error(PROCESS_MANAGER_LOG_MODULE, "进程启动异常: {}", e.what()); - process_info_ptr->state = process_state::FAILED; - process_info_ptr->error_message = e.what(); - return 0; - } - } - catch (const std::exception& e) { - log_module_error(PROCESS_MANAGER_LOG_MODULE, "创建进程信息异常: {}", e.what()); - return 0; - } -} + // 创建进程信息对象 + auto process_info_ptr = std::make_unique( + process_id, name, executable_path, arguments, type); -process_error process_manager::terminate_process( - uint32_t process_id, - bool force, - std::chrono::milliseconds timeout_ms -) { - std::lock_guard lock(manager_mutex_); - return terminate_process_internal(process_id, force, timeout_ms); -} + // 准备启动进程 + log_module_info(PROCESS_MANAGER_LOG_MODULE, "启动进程: 名称={}, 路径={}, ID={}", + name, executable_path, process_id); -process_error process_manager::terminate_process_internal( - uint32_t process_id, - bool force, - std::chrono::milliseconds timeout_ms -) { - // 注意:调用此方法时必须已经持有manager_mutex_锁! - - // 查找进程信息 - auto it = processes_.find(process_id); - if (it == processes_.end()) { - log_module_warn(PROCESS_MANAGER_LOG_MODULE, "尝试终止未管理的进程: ID={}", process_id); - return process_error::PROCESS_NOT_RUNNING; - } - - auto& process_info = it->second; - - // 检查进程是否在运行 - if (!process_info->is_running() || !process_info->process) { - log_module_warn(PROCESS_MANAGER_LOG_MODULE, "尝试终止未运行的进程: ID={}", process_id); - return process_error::PROCESS_NOT_RUNNING; - } - - // 停止监控器 - auto monitor_it = monitors_.find(process_id); - if (monitor_it != monitors_.end()) { - monitor_it->second->stop(); - } - - try { - // boost 1.89.0 API: terminate()和wait()方法已改变 - // 先尝试正常终止进程 - if (!force) { - log_module_info(PROCESS_MANAGER_LOG_MODULE, "正常终止进程: ID={}", process_id); - process_info->process->terminate(); - - // 使用异步等待实现超时功能(因为wait_for已移除) - auto wait_future = std::async(std::launch::async, [&process_info]() { - process_info->process->wait(); - }); - - if (wait_future.wait_for(timeout_ms) == std::future_status::timeout) { - // 如果等待超时,则强制终止 - log_module_warn(PROCESS_MANAGER_LOG_MODULE, "进程终止超时,强制终止: ID={}", process_id); - - #ifdef _WIN32 - // Windows使用TerminateProcess - ::TerminateProcess(process_info->process->native_handle(), 1); - #else - // POSIX使用SIGKILL - ::kill(process_info->process->id(), SIGKILL); - #endif - - process_info->process->wait(); - } - } - // 强制终止进程 - else { - log_module_info(PROCESS_MANAGER_LOG_MODULE, "强制终止进程: ID={}", process_id); - - #ifdef _WIN32 - ::TerminateProcess(process_info->process->native_handle(), 1); - #else - ::kill(process_info->process->id(), SIGKILL); - #endif - - process_info->process->wait(); - } - - // 检查进程是否已经终止 - if (process_info->process->running()) { - log_module_error(PROCESS_MANAGER_LOG_MODULE, "进程终止失败: ID={}", process_id); - return process_error::TERMINATE_FAILED; - } - - // 更新进程状态 (boost 1.89.0: exit_code()已改为通过wait()获取) - process_info->state = process_state::STOPPED; - process_info->exit_code = process_info->process->exit_code(); - - log_module_info(PROCESS_MANAGER_LOG_MODULE, "进程已终止: ID={}, 退出码={}", - process_id, process_info->exit_code); - - // 移除监控器 - if (monitor_it != monitors_.end()) { - monitors_.erase(monitor_it); - } - - // 立即从映射中移除已终止的进程 - processes_.erase(it); - log_module_debug(PROCESS_MANAGER_LOG_MODULE, "已从进程列表中除: ID={}", process_id); - - return process_error::SUCCESS; - } - catch (const std::exception& e) { - log_module_error(PROCESS_MANAGER_LOG_MODULE, "终止进程异常: {}, ID={}", e.what(), process_id); - return process_error::TERMINATE_FAILED; - } -} + // 构建命令行参数字符串 + std::stringstream args_stream; + for (const auto& arg : arguments) { + args_stream << " " << arg; + } -process_error process_manager::terminate_all_processes( - bool force, - std::chrono::milliseconds timeout_ms -) { - std::lock_guard lock(manager_mutex_); - - log_module_info(PROCESS_MANAGER_LOG_MODULE, "终止所有进程: 数量={}", processes_.size()); - - process_error result = process_error::SUCCESS; - - // 记录所有进程ID,以防在循环中修改容器 - std::vector process_ids; - for (const auto& pair : processes_) { - process_ids.push_back(pair.first); - } - - // 终止所有进程 - 使用内部方法避免死锁 - for (uint32_t id : process_ids) { - process_error err = terminate_process_internal(id, force, timeout_ms); - if (err != process_error::SUCCESS && err != process_error::PROCESS_NOT_RUNNING) { - result = err; - } - } - - // 清理所有监控器 - monitors_.clear(); - - // 注意:进程记录已在terminate_process_internal中移除,无需再次清理 - - log_module_info(PROCESS_MANAGER_LOG_MODULE, "所有进程终止操作完成"); - return result; -} + // 记录启动状态 + process_info_ptr->state = process_state::STARTING; + process_info_ptr->start_time = std::chrono::system_clock::now(); -const process_info* process_manager::get_process_info(uint32_t process_id) const { - std::lock_guard lock(manager_mutex_); - - auto it = processes_.find(process_id); - if (it != processes_.end()) { - return it->second.get(); - } - - return nullptr; -} + try { + // 使用Boost.Process启动子进程 (boost 1.89.0 API) + namespace bp = boost::process; -std::vector process_manager::get_all_process_ids() const { - std::lock_guard lock(manager_mutex_); - - std::vector ids; - ids.reserve(processes_.size()); - - for (const auto& pair : processes_) { - ids.push_back(pair.first); - } - - return ids; -} + // 创建子进程对象(boost 1.89.0正确语法:直接传递参数向量) + process_info_ptr->process = std::make_unique( + io_context_, + executable_path, + arguments, + bp::process_stdio{} + ); -size_t process_manager::process_count() const { - std::lock_guard lock(manager_mutex_); - return processes_.size(); -} + // 检查进程是否成功启动 + if (!process_info_ptr->process->running()) { + log_module_error(PROCESS_MANAGER_LOG_MODULE, "进程启动失败: {}", executable_path); + return 0; + } -bool process_manager::has_process(uint32_t process_id) const { - std::lock_guard lock(manager_mutex_); - return processes_.find(process_id) != processes_.end(); -} + // 保持STARTING状态,让监控器检测后更新为RUNNING + // 这样可以触发状态变化回调 + // process_info_ptr->state = process_state::RUNNING; -bool process_manager::is_process_running(uint32_t process_id) const { - std::lock_guard lock(manager_mutex_); - - auto it = processes_.find(process_id); - if (it != processes_.end() && it->second->process) { - try { - return it->second->process->running(); - } - catch (const std::exception& e) { - log_module_error(PROCESS_MANAGER_LOG_MODULE, "检查进程运行状态异常: {}, ID={}", e.what(), process_id); - return false; - } - } - - return false; -} + // 添加进程到管理列表 + processes_[process_id] = std::move(process_info_ptr); -void process_manager::set_state_change_callback(process_monitor::state_change_callback callback) { - std::lock_guard lock(manager_mutex_); - - state_change_callback_ = std::move(callback); - - // 为所有现有的监控器设置回调 - for (auto& pair : monitors_) { - pair.second->set_state_change_callback(state_change_callback_); - } -} + // 如果需要监控,则创建进程监控器 + if (monitor) { + create_process_monitor(*processes_[process_id]); + } -void process_manager::set_resource_callback(process_monitor::resource_callback callback) { - std::lock_guard lock(manager_mutex_); - - resource_callback_ = std::move(callback); - - // 为所有现有的监控器设置回调 - for (auto& pair : monitors_) { - pair.second->set_resource_callback(resource_callback_); - } -} + log_module_info(PROCESS_MANAGER_LOG_MODULE, "进程启动成功: 名称={}, ID={}", name, process_id); + return process_id; + } + catch (const std::exception& e) { + log_module_error(PROCESS_MANAGER_LOG_MODULE, "进程启动异常: {}", e.what()); + process_info_ptr->state = process_state::FAILED; + process_info_ptr->error_message = e.what(); + return 0; + } + } + catch (const std::exception& e) { + log_module_error(PROCESS_MANAGER_LOG_MODULE, "创建进程信息异常: {}", e.what()); + return 0; + } + } -void process_manager::set_error_callback(process_monitor::error_callback callback) { - std::lock_guard lock(manager_mutex_); - - error_callback_ = std::move(callback); - - // 为所有现有的监控器设置回调 - for (auto& pair : monitors_) { - pair.second->set_error_callback(error_callback_); - } -} + process_error process_manager::terminate_process( + uint32_t process_id, + bool force, + std::chrono::milliseconds timeout_ms + ) { + std::lock_guard lock(manager_mutex_); + return terminate_process_internal(process_id, force, timeout_ms); + } -uint32_t process_manager::generate_process_id() { - // 简单地使用递增的ID,确保唯一性 - return next_process_id_++; -} + process_error process_manager::terminate_process_internal( + uint32_t process_id, + bool force, + std::chrono::milliseconds timeout_ms + ) { + // 注意:调用此方法时必须已经持有manager_mutex_锁! -void process_manager::cleanup_processes() { - // 记录要移除的进程ID - std::vector ids_to_remove; - - for (const auto& pair : processes_) { - const auto& process_info = pair.second; - - // 检查进程是否已结束或无效 - if (process_info->state == process_state::STOPPED || - process_info->state == process_state::FAILED || - !process_info->process) { - ids_to_remove.push_back(pair.first); - } - } - - // 移除无效的进程记录 - for (uint32_t id : ids_to_remove) { - log_module_debug(PROCESS_MANAGER_LOG_MODULE, "清理进程记录: ID={}", id); - processes_.erase(id); - } -} + // 查找进程信息 + auto it = processes_.find(process_id); + if (it == processes_.end()) { + log_module_warn(PROCESS_MANAGER_LOG_MODULE, "尝试终止未管理的进程: ID={}", process_id); + return process_error::PROCESS_NOT_RUNNING; + } -void process_manager::create_process_monitor(process_info& process) { - try { - // 创建监控器 - auto monitor = std::make_unique(process); - - // 设置回调函数 - if (state_change_callback_) { - monitor->set_state_change_callback(state_change_callback_); - } - - if (resource_callback_) { - monitor->set_resource_callback(resource_callback_); - } - - if (error_callback_) { - monitor->set_error_callback(error_callback_); - } - - // 启动监控器 - process_error result = monitor->start(); - if (result != process_error::SUCCESS) { - log_module_error(PROCESS_MANAGER_LOG_MODULE, "启动进程监控器败: {}, ID={}", - process_error_to_string(result), process.id); - return; - } - - // 添加到监控器列表 - monitors_[process.id] = std::move(monitor); - - log_module_debug(PROCESS_MANAGER_LOG_MODULE, "创建进程监控器: ID={}", process.id); - } - catch (const std::exception& e) { - log_module_error(PROCESS_MANAGER_LOG_MODULE, "创建进程监控器异常: {}, ID={}", e.what(), process.id); - } -} + auto& process_info = it->second; -} // namespace alicho \ No newline at end of file + // 检查进程是否在运行 + if (!process_info->is_running() || !process_info->process) { + log_module_warn(PROCESS_MANAGER_LOG_MODULE, "尝试终止未运行的进程: ID={}", process_id); + return process_error::PROCESS_NOT_RUNNING; + } + + // 停止监控器 + auto monitor_it = monitors_.find(process_id); + if (monitor_it != monitors_.end()) { + monitor_it->second->stop(); + } + + try { + // boost 1.89.0 API: terminate()和wait()方法已改变 + // 先尝试正常终止进程 + if (!force) { + log_module_info(PROCESS_MANAGER_LOG_MODULE, "正常终止进程: ID={}", process_id); + process_info->process->terminate(); + + // 使用异步等待实现超时功能(因为wait_for已移除) + auto wait_future = std::async(std::launch::async, [&process_info]() { + process_info->process->wait(); + }); + + if (wait_future.wait_for(timeout_ms) == std::future_status::timeout) { + // 如果等待超时,则强制终止 + log_module_warn(PROCESS_MANAGER_LOG_MODULE, "进程终止超时,强制终止: ID={}", process_id); + + #ifdef _WIN32 + // Windows使用TerminateProcess + ::TerminateProcess(process_info->process->native_handle(), 1); + #else + // POSIX使用SIGKILL + ::kill(process_info->process->id(), SIGKILL); + #endif + + process_info->process->wait(); + } + } + // 强制终止进程 + else { + log_module_info(PROCESS_MANAGER_LOG_MODULE, "强制终止进程: ID={}", process_id); + + #ifdef _WIN32 + ::TerminateProcess(process_info->process->native_handle(), 1); + #else + ::kill(process_info->process->id(), SIGKILL); + #endif + + process_info->process->wait(); + } + + // 检查进程是否已经终止 + if (process_info->process->running()) { + log_module_error(PROCESS_MANAGER_LOG_MODULE, "进程终止失败: ID={}", process_id); + return process_error::TERMINATE_FAILED; + } + + // 更新进程状态 (boost 1.89.0: exit_code()已改为通过wait()获取) + process_info->state = process_state::STOPPED; + process_info->exit_code = process_info->process->exit_code(); + + log_module_info(PROCESS_MANAGER_LOG_MODULE, "进程已终止: ID={}, 退出码={}", + process_id, process_info->exit_code); + + // 移除监控器 + if (monitor_it != monitors_.end()) { + monitors_.erase(monitor_it); + } + + // 立即从映射中移除已终止的进程 + processes_.erase(it); + log_module_debug(PROCESS_MANAGER_LOG_MODULE, "已从进程列表中除: ID={}", process_id); + + return process_error::SUCCESS; + } + catch (const std::exception& e) { + log_module_error(PROCESS_MANAGER_LOG_MODULE, "终止进程异常: {}, ID={}", e.what(), process_id); + return process_error::TERMINATE_FAILED; + } + } + + process_error process_manager::terminate_all_processes( + bool force, + std::chrono::milliseconds timeout_ms + ) { + std::lock_guard lock(manager_mutex_); + + log_module_info(PROCESS_MANAGER_LOG_MODULE, "终止所有进程: 数量={}", processes_.size()); + + process_error result = process_error::SUCCESS; + + // 记录所有进程ID,以防在循环中修改容器 + std::vector process_ids; + for (const auto& pair : processes_) { + process_ids.push_back(pair.first); + } + + // 终止所有进程 - 使用内部方法避免死锁 + for (uint32_t id : process_ids) { + process_error err = terminate_process_internal(id, force, timeout_ms); + if (err != process_error::SUCCESS && err != process_error::PROCESS_NOT_RUNNING) { + result = err; + } + } + + // 清理所有监控器 + monitors_.clear(); + + // 注意:进程记录已在terminate_process_internal中移除,无需再次清理 + + log_module_info(PROCESS_MANAGER_LOG_MODULE, "所有进程终止操作完成"); + return result; + } + + const process_info* process_manager::get_process_info(uint32_t process_id) const { + std::lock_guard lock(manager_mutex_); + + auto it = processes_.find(process_id); + if (it != processes_.end()) { + return it->second.get(); + } + + return nullptr; + } + + std::vector process_manager::get_all_process_ids() const { + std::lock_guard lock(manager_mutex_); + + std::vector ids; + ids.reserve(processes_.size()); + + for (const auto& pair : processes_) { + ids.push_back(pair.first); + } + + return ids; + } + + size_t process_manager::process_count() const { + std::lock_guard lock(manager_mutex_); + return processes_.size(); + } + + bool process_manager::has_process(uint32_t process_id) const { + std::lock_guard lock(manager_mutex_); + return processes_.find(process_id) != processes_.end(); + } + + bool process_manager::is_process_running(uint32_t process_id) const { + std::lock_guard lock(manager_mutex_); + + auto it = processes_.find(process_id); + if (it != processes_.end() && it->second->process) { + try { + return it->second->process->running(); + } + catch (const std::exception& e) { + log_module_error(PROCESS_MANAGER_LOG_MODULE, "检查进程运行状态异常: {}, ID={}", e.what(), process_id); + return false; + } + } + + return false; + } + + void process_manager::set_state_change_callback(process_monitor::state_change_callback callback) { + std::lock_guard lock(manager_mutex_); + + state_change_callback_ = std::move(callback); + + // 为所有现有的监控器设置回调 + for (auto& pair : monitors_) { + pair.second->set_state_change_callback(state_change_callback_); + } + } + + void process_manager::set_resource_callback(process_monitor::resource_callback callback) { + std::lock_guard lock(manager_mutex_); + + resource_callback_ = std::move(callback); + + // 为所有现有的监控器设置回调 + for (auto& pair : monitors_) { + pair.second->set_resource_callback(resource_callback_); + } + } + + void process_manager::set_error_callback(process_monitor::error_callback callback) { + std::lock_guard lock(manager_mutex_); + + error_callback_ = std::move(callback); + + // 为所有现有的监控器设置回调 + for (auto& pair : monitors_) { + pair.second->set_error_callback(error_callback_); + } + } + + uint32_t process_manager::generate_process_id() { + // 简单地使用递增的ID,确保唯一性 + return next_process_id_++; + } + + void process_manager::cleanup_processes() { + // 记录要移除的进程ID + std::vector ids_to_remove; + + for (const auto& pair : processes_) { + const auto& process_info = pair.second; + + // 检查进程是否已结束或无效 + if (process_info->state == process_state::STOPPED || + process_info->state == process_state::FAILED || + !process_info->process) { + ids_to_remove.push_back(pair.first); + } + } + + // 移除无效的进程记录 + for (uint32_t id : ids_to_remove) { + log_module_debug(PROCESS_MANAGER_LOG_MODULE, "清理进程记录: ID={}", id); + processes_.erase(id); + } + } + + void process_manager::create_process_monitor(process_info& process) { + try { + // 创建监控器 + auto monitor = std::make_unique(process); + + // 设置回调函数 + if (state_change_callback_) { + monitor->set_state_change_callback(state_change_callback_); + } + + if (resource_callback_) { + monitor->set_resource_callback(resource_callback_); + } + + if (error_callback_) { + monitor->set_error_callback(error_callback_); + } + + // 启动监控器 + process_error result = monitor->start(); + if (result != process_error::SUCCESS) { + log_module_error(PROCESS_MANAGER_LOG_MODULE, "启动进程监控器败: {}, ID={}", + process_error_to_string(result), process.id); + return; + } + + // 添加到监控器列表 + monitors_[process.id] = std::move(monitor); + + log_module_debug(PROCESS_MANAGER_LOG_MODULE, "创建进程监控器: ID={}", process.id); + } + catch (const std::exception& e) { + log_module_error(PROCESS_MANAGER_LOG_MODULE, "创建进程监控器异常: {}, ID={}", e.what(), process.id); + } + } +} // namespace alicho diff --git a/src/process_manager/process_manager.h b/src/process_manager/process_manager.h index b21765c..db8accd 100644 --- a/src/process_manager/process_manager.h +++ b/src/process_manager/process_manager.h @@ -12,170 +12,168 @@ #include "process_types.h" namespace alicho { + /** + * @brief 进程管理器类,负责沙箱进程的创建和管理 + * + * 实现为单例模式,管理多个沙箱进程的生命周期,包括启动、停止和监控等功能。 + * 使用Boost.Process库进行底层进程操作,并集成process_monitor进行状态监控。 + */ + class process_manager : public lazy_singleton { + friend class lazy_singleton; -/** - * @brief 进程管理器类,负责沙箱进程的创建和管理 - * - * 实现为单例模式,管理多个沙箱进程的生命周期,包括启动、停止和监控等功能。 - * 使用Boost.Process库进行底层进程操作,并集成process_monitor进行状态监控。 - */ -class process_manager : public lazy_singleton { - friend class lazy_singleton; + public: + /** + * @brief 启动沙盒进程 + * + * @param name 进程名称 + * @param executable_path 可执行文件路径 + * @param arguments 命令行参数 + * @param type 沙盒类型 + * @param monitor 是否启用监控 + * @return uint32_t 进程ID,失败返回0 + */ + uint32_t launch_process( + const std::string& name, + const std::string& executable_path, + const std::vector& arguments, + sandbox_type type = sandbox_type::HOST, + bool monitor = true + ); -public: - /** - * @brief 启动沙盒进程 - * - * @param name 进程名称 - * @param executable_path 可执行文件路径 - * @param arguments 命令行参数 - * @param type 沙盒类型 - * @param monitor 是否启用监控 - * @return uint32_t 进程ID,失败返回0 - */ - uint32_t launch_process( - const std::string& name, - const std::string& executable_path, - const std::vector& arguments, - sandbox_type type = sandbox_type::HOST, - bool monitor = true - ); + /** + * @brief 终止指定ID的进程 + * + * @param process_id 进程ID + * @param force 是否强制终止 + * @param timeout_ms 等待超时时间(毫秒) + * @return process_error 操作结果 + */ + process_error terminate_process( + uint32_t process_id, + bool force = false, + std::chrono::milliseconds timeout_ms = std::chrono::milliseconds(5000) + ); - /** - * @brief 终止指定ID的进程 - * - * @param process_id 进程ID - * @param force 是否强制终止 - * @param timeout_ms 等待超时时间(毫秒) - * @return process_error 操作结果 - */ - process_error terminate_process( - uint32_t process_id, - bool force = false, - std::chrono::milliseconds timeout_ms = std::chrono::milliseconds(5000) - ); + /** + * @brief 终止所有管理的进程 + * + * @param force 是否强制终止 + * @param timeout_ms 等待超时时间(毫秒) + * @return process_error 操作结果 + */ + process_error terminate_all_processes( + bool force = false, + std::chrono::milliseconds timeout_ms = std::chrono::milliseconds(5000) + ); - /** - * @brief 终止所有管理的进程 - * - * @param force 是否强制终止 - * @param timeout_ms 等待超时时间(毫秒) - * @return process_error 操作结果 - */ - process_error terminate_all_processes( - bool force = false, - std::chrono::milliseconds timeout_ms = std::chrono::milliseconds(5000) - ); + /** + * @brief 获取指定ID的进程信息 + * + * @param process_id 进程ID + * @return const process_info* 进程信息指针,未找到则返回nullptr + */ + const process_info* get_process_info(uint32_t process_id) const; - /** - * @brief 获取指定ID的进程信息 - * - * @param process_id 进程ID - * @return const process_info* 进程信息指针,未找到则返回nullptr - */ - const process_info* get_process_info(uint32_t process_id) const; + /** + * @brief 获取所有管理的进程ID列表 + * + * @return std::vector 进程ID列表 + */ + std::vector get_all_process_ids() const; - /** - * @brief 获取所有管理的进程ID列表 - * - * @return std::vector 进程ID列表 - */ - std::vector get_all_process_ids() const; + /** + * @brief 获取所有管理的进程数量 + * + * @return size_t 进程数量 + */ + size_t process_count() const; - /** - * @brief 获取所有管理的进程数量 - * - * @return size_t 进程数量 - */ - size_t process_count() const; + /** + * @brief 检查指定ID的进程是否存在 + * + * @param process_id 进程ID + * @return bool 进程是否存在 + */ + bool has_process(uint32_t process_id) const; - /** - * @brief 检查指定ID的进程是否存在 - * - * @param process_id 进程ID - * @return bool 进程是否存在 - */ - bool has_process(uint32_t process_id) const; + /** + * @brief 检查指定ID的进程是否在运行 + * + * @param process_id 进程ID + * @return bool 进程是否在运行 + */ + bool is_process_running(uint32_t process_id) const; - /** - * @brief 检查指定ID的进程是否在运行 - * - * @param process_id 进程ID - * @return bool 进程是否在运行 - */ - bool is_process_running(uint32_t process_id) const; + /** + * @brief 设置进程状态变化回调函数 + * + * @param callback 回调函数 + */ + void set_state_change_callback(process_monitor::state_change_callback callback); - /** - * @brief 设置进程状态变化回调函数 - * - * @param callback 回调函数 - */ - void set_state_change_callback(process_monitor::state_change_callback callback); + /** + * @brief 设置进程资源使用回调函数 + * + * @param callback 回调函数 + */ + void set_resource_callback(process_monitor::resource_callback callback); - /** - * @brief 设置进程资源使用回调函数 - * - * @param callback 回调函数 - */ - void set_resource_callback(process_monitor::resource_callback callback); + /** + * @brief 设置进程错误回调函数 + * + * @param callback 回调函数 + */ + void set_error_callback(process_monitor::error_callback callback); - /** - * @brief 设置进程错误回调函数 - * - * @param callback 回调函数 - */ - void set_error_callback(process_monitor::error_callback callback); + private: + // 私有构造函数和析构函数 + process_manager(); + ~process_manager(); -private: - // 私有构造函数和析构函数 - process_manager(); - ~process_manager(); + // 生成唯一的进程ID + uint32_t generate_process_id(); - // 生成唯一的进程ID - uint32_t generate_process_id(); + // 清理无效的进程记录 + void cleanup_processes(); - // 清理无效的进程记录 - void cleanup_processes(); + // 实际启动进程的内部方法 + uint32_t launch_process_internal( + const std::string& name, + const std::string& executable_path, + const std::vector& arguments, + sandbox_type type, + bool monitor + ); - // 实际启动进程的内部方法 - uint32_t launch_process_internal( - const std::string& name, - const std::string& executable_path, - const std::vector& arguments, - sandbox_type type, - bool monitor - ); + // 终止进程的内部方法(不加锁,供terminate_all_processes调用) + process_error terminate_process_internal( + uint32_t process_id, + bool force, + std::chrono::milliseconds timeout_ms + ); - // 终止进程的内部方法(不加锁,供terminate_all_processes调用) - process_error terminate_process_internal( - uint32_t process_id, - bool force, - std::chrono::milliseconds timeout_ms - ); + // 创建进程监控器 + void create_process_monitor(process_info& process); - // 创建进程监控器 - void create_process_monitor(process_info& process); + private: + // 进程信息映射表,key为进程ID + std::map> processes_; -private: - // 进程信息映射表,key为进程ID - std::map> processes_; - - // 进程监控器映射表,key为进程ID - std::map> monitors_; - - // 同步互斥量 - mutable std::mutex manager_mutex_; - - // 下一个可用的进程ID - uint32_t next_process_id_; - - // Boost.Asio IO上下文 (boost 1.89.0需要) - boost::asio::io_context io_context_; - - // 回调函数 - process_monitor::state_change_callback state_change_callback_; - process_monitor::resource_callback resource_callback_; - process_monitor::error_callback error_callback_; -}; + // 进程监控器映射表,key为进程ID + std::map> monitors_; -} // namespace alicho \ No newline at end of file + // 同步互斥量 + mutable std::mutex manager_mutex_; + + // 下一个可用的进程ID + uint32_t next_process_id_; + + // Boost.Asio IO上下文 (boost 1.89.0需要) + boost::asio::io_context io_context_; + + // 回调函数 + process_monitor::state_change_callback state_change_callback_; + process_monitor::resource_callback resource_callback_; + process_monitor::error_callback error_callback_; + }; +} // namespace alicho diff --git a/src/process_manager/process_monitor.cpp b/src/process_manager/process_monitor.cpp index fcd95ed..4664043 100644 --- a/src/process_manager/process_monitor.cpp +++ b/src/process_manager/process_monitor.cpp @@ -23,299 +23,296 @@ #define log_module_error(module, ...) SPDLOG_LOGGER_ERROR(spdlog::default_logger(), "[{}] {}", module, fmt::format(__VA_ARGS__)) namespace alicho { + process_monitor::process_monitor( + process_info& process_to_monitor, + std::chrono::milliseconds monitor_interval + ) : monitored_process_(process_to_monitor), + monitor_interval_(monitor_interval), + running_(false), + stop_requested_(false) { + log_module_debug(PROCESS_MONITOR_LOG_MODULE, "创建进程监控器,进程ID: {}, 名称: {}", + monitored_process_.id, monitored_process_.name); + } -process_monitor::process_monitor( - process_info& process_to_monitor, - std::chrono::milliseconds monitor_interval -) : monitored_process_(process_to_monitor), - monitor_interval_(monitor_interval), - running_(false), - stop_requested_(false) { - - log_module_debug(PROCESS_MONITOR_LOG_MODULE, "创建进程监控器,进程ID: {}, 名称: {}", - monitored_process_.id, monitored_process_.name); -} + process_monitor::~process_monitor() { + stop(); + log_module_debug(PROCESS_MONITOR_LOG_MODULE, "销毁进程监控器,进程ID: {}", + monitored_process_.id); + } -process_monitor::~process_monitor() { - stop(); - log_module_debug(PROCESS_MONITOR_LOG_MODULE, "销毁进程监控器,进程ID: {}", - monitored_process_.id); -} + process_error process_monitor::start() { + std::lock_guard lock(monitor_mutex_); -process_error process_monitor::start() { - std::lock_guard lock(monitor_mutex_); - - if (running_) { - log_module_warn(PROCESS_MONITOR_LOG_MODULE, "尝试启动已运行的监控器,进程ID: {}", - monitored_process_.id); - return process_error::PROCESS_ALREADY_RUNNING; - } - - try { - stop_requested_ = false; - running_ = true; - monitor_thread_ = std::make_unique(&process_monitor::monitor_loop, this); - log_module_info(PROCESS_MONITOR_LOG_MODULE, "启动监控器,进程ID: {}", - monitored_process_.id); - return process_error::SUCCESS; - } - catch (const std::exception& e) { - running_ = false; - log_module_error(PROCESS_MONITOR_LOG_MODULE, "启动监控线程失败: {}", e.what()); - return process_error::MONITOR_ERROR; - } -} + if (running_) { + log_module_warn(PROCESS_MONITOR_LOG_MODULE, "尝试启动已运行的监控器,进程ID: {}", + monitored_process_.id); + return process_error::PROCESS_ALREADY_RUNNING; + } -process_error process_monitor::stop() { - std::lock_guard lock(monitor_mutex_); - - if (!running_) { - return process_error::PROCESS_NOT_RUNNING; - } - - try { - stop_requested_ = true; - - // 等待监控线程完成 - if (monitor_thread_ && monitor_thread_->joinable()) { - monitor_thread_->join(); - } - - monitor_thread_.reset(); - running_ = false; - log_module_info(PROCESS_MONITOR_LOG_MODULE, "停止监控器,进程ID: {}", - monitored_process_.id); - return process_error::SUCCESS; - } - catch (const std::exception& e) { - log_module_error(PROCESS_MONITOR_LOG_MODULE, "停止监控线程失败: {}", e.what()); - return process_error::MONITOR_ERROR; - } -} + try { + stop_requested_ = false; + running_ = true; + monitor_thread_ = std::make_unique(&process_monitor::monitor_loop, this); + log_module_info(PROCESS_MONITOR_LOG_MODULE, "启动监控器,进程ID: {}", + monitored_process_.id); + return process_error::SUCCESS; + } + catch (const std::exception& e) { + running_ = false; + log_module_error(PROCESS_MONITOR_LOG_MODULE, "启动监控线程失败: {}", e.what()); + return process_error::MONITOR_ERROR; + } + } -process_error process_monitor::update_status() { - try { - auto previous_state = monitored_process_.state; - - // 检查进程状态 - bool is_running = check_process_running(); - - if (is_running) { - // 如果进程正在运行,更新资源使用情况 - if (monitored_process_.state != process_state::RUNNING) { - monitored_process_.state = process_state::RUNNING; - notify_state_change(process_state::RUNNING); - } - - update_resource_usage(); - } - else { - // 如果进程不在运行,更新状态 - if (monitored_process_.state == process_state::RUNNING || - monitored_process_.state == process_state::STARTING) { - monitored_process_.state = process_state::STOPPED; - notify_state_change(process_state::STOPPED); - } - } - - return process_error::SUCCESS; - } - catch (const std::exception& e) { - log_module_error(PROCESS_MONITOR_LOG_MODULE, "更新进程状态失败: {}", e.what()); - notify_error(process_error::MONITOR_ERROR, e.what()); - return process_error::MONITOR_ERROR; - } -} + process_error process_monitor::stop() { + std::lock_guard lock(monitor_mutex_); -bool process_monitor::is_running() const { - std::lock_guard lock(monitor_mutex_); - return running_; -} + if (!running_) { + return process_error::PROCESS_NOT_RUNNING; + } -void process_monitor::set_monitor_interval(std::chrono::milliseconds interval) { - std::lock_guard lock(monitor_mutex_); - monitor_interval_ = interval; - log_module_debug(PROCESS_MONITOR_LOG_MODULE, "设置监控间隔为 {}ms,进程ID: {}", - interval.count(), monitored_process_.id); -} + try { + stop_requested_ = true; -void process_monitor::set_state_change_callback(state_change_callback callback) { - std::lock_guard lock(monitor_mutex_); - state_change_callback_ = std::move(callback); -} + // 等待监控线程完成 + if (monitor_thread_ && monitor_thread_->joinable()) { + monitor_thread_->join(); + } -void process_monitor::set_resource_callback(resource_callback callback) { - std::lock_guard lock(monitor_mutex_); - resource_callback_ = std::move(callback); -} + monitor_thread_.reset(); + running_ = false; + log_module_info(PROCESS_MONITOR_LOG_MODULE, "停止监控器,进程ID: {}", + monitored_process_.id); + return process_error::SUCCESS; + } + catch (const std::exception& e) { + log_module_error(PROCESS_MONITOR_LOG_MODULE, "停止监控线程失败: {}", e.what()); + return process_error::MONITOR_ERROR; + } + } -void process_monitor::set_error_callback(error_callback callback) { - std::lock_guard lock(monitor_mutex_); - error_callback_ = std::move(callback); -} + process_error process_monitor::update_status() { + try { + auto previous_state = monitored_process_.state; -void process_monitor::monitor_loop() { - log_module_debug(PROCESS_MONITOR_LOG_MODULE, "监控线程启动,进程ID: {}", - monitored_process_.id); - - while (!stop_requested_) { - try { - update_status(); - } - catch (const std::exception& e) { - log_module_error(PROCESS_MONITOR_LOG_MODULE, "监控循环发生异常: {}", e.what()); - notify_error(process_error::MONITOR_ERROR, e.what()); - - // 出现异常时短暂休眠,避免频繁报错 - std::this_thread::sleep_for(std::chrono::milliseconds(500)); - } - - // 等待直到下一个监控周期或者停止请求 - std::this_thread::sleep_for(monitor_interval_); - } - - log_module_debug(PROCESS_MONITOR_LOG_MODULE, "监控线程退出,进程ID: {}", - monitored_process_.id); -} + // 检查进程状态 + bool is_running = check_process_running(); -bool process_monitor::check_process_running() { - if (!monitored_process_.process) { - // 进程对象为空,可能尚未启动 - return false; - } - - try { - return monitored_process_.process->running(); - } - catch (const std::exception& e) { - log_module_error(PROCESS_MONITOR_LOG_MODULE, "检查进程运行状态失败: {}", e.what()); - return false; - } -} + if (is_running) { + // 如果进程正在运行,更新资源使用情况 + if (monitored_process_.state != process_state::RUNNING) { + monitored_process_.state = process_state::RUNNING; + notify_state_change(process_state::RUNNING); + } -void process_monitor::update_resource_usage() { - try { - process_resource_usage usage; - - // 计算进程运行时间 - auto now = std::chrono::system_clock::now(); - usage.uptime = std::chrono::duration_cast( - now - monitored_process_.start_time); - -#if defined(_WIN32) - if (!monitored_process_.process) { - return; - } - - // 获取进程句柄 - HANDLE process_handle = monitored_process_.process->native_handle(); - if (process_handle == nullptr || process_handle == INVALID_HANDLE_VALUE) { - log_module_error(PROCESS_MONITOR_LOG_MODULE, "无效的进程句柄"); - return; - } - - // 获取内存使用情况 - PROCESS_MEMORY_COUNTERS_EX pmc; - if (GetProcessMemoryInfo(process_handle, (PROCESS_MEMORY_COUNTERS*)&pmc, sizeof(pmc))) { - usage.memory_usage_kb = pmc.WorkingSetSize / 1024; - } - - // 获取CPU使用率 (Windows实现较复杂,这里仅作简化处理) - // 实际应用中可能需要更复杂的计算,这里简单设置为0 - usage.cpu_percent = 0.0; -#elif defined(__linux__) - if (!monitored_process_.process) { - return; - } - - int pid = monitored_process_.process->id(); - - // 读取/proc/{pid}/stat文件获取进程信息 - std::string proc_stat_path = "/proc/" + std::to_string(pid) + "/stat"; - std::ifstream stat_file(proc_stat_path); - if (stat_file.is_open()) { - std::string stat_content; - std::getline(stat_file, stat_content); - - // 解析/proc/{pid}/statm获取内存信息 - std::string proc_statm_path = "/proc/" + std::to_string(pid) + "/statm"; - std::ifstream statm_file(proc_statm_path); - if (statm_file.is_open()) { - long rss; - statm_file >> rss; - - // 转换为KB (页面大小通常为4KB) - usage.memory_usage_kb = rss * 4; - } - - // 简化CPU使用率计算,实际应用需更复杂的处理 - usage.cpu_percent = 0.0; - } -#elif defined(__APPLE__) - // macOS实现,简化处理 - usage.memory_usage_kb = 0; - usage.cpu_percent = 0.0; -#endif - - // 更新进程信息 - monitored_process_.resource_usage = usage; - - // 触发回调 - notify_resource_usage(usage); - } - catch (const std::exception& e) { - log_module_error(PROCESS_MONITOR_LOG_MODULE, "更新资源使用情况失败: {}", e.what()); - notify_error(process_error::MONITOR_ERROR, e.what()); - } -} + update_resource_usage(); + } + else { + // 如果进程不在运行,更新状态 + if (monitored_process_.state == process_state::RUNNING || + monitored_process_.state == process_state::STARTING) { + monitored_process_.state = process_state::STOPPED; + notify_state_change(process_state::STOPPED); + } + } -void process_monitor::notify_state_change(process_state new_state) { - if (state_change_callback_) { - try { - state_change_callback_(monitored_process_, new_state); - } - catch (const std::exception& e) { - log_module_error(PROCESS_MONITOR_LOG_MODULE, "状态变化回调异: {}", e.what()); - } - } - - log_module_info(PROCESS_MONITOR_LOG_MODULE, "进程状态变化: {} -> {},进程ID: {}", - process_state_to_string(monitored_process_.state), - process_state_to_string(new_state), - monitored_process_.id); -} + return process_error::SUCCESS; + } + catch (const std::exception& e) { + log_module_error(PROCESS_MONITOR_LOG_MODULE, "更新进程状态失败: {}", e.what()); + notify_error(process_error::MONITOR_ERROR, e.what()); + return process_error::MONITOR_ERROR; + } + } -void process_monitor::notify_resource_usage(const process_resource_usage& usage) { - if (resource_callback_) { - try { - resource_callback_(monitored_process_, usage); - } - catch (const std::exception& e) { - log_module_error(PROCESS_MONITOR_LOG_MODULE, "资源使用回调异常: {}", e.what()); - } - } - - log_module_trace(PROCESS_MONITOR_LOG_MODULE, "进程资源使用: 内存={} KB, CPU={:.2f}%, 运行时间={}ms, 进程ID: {}", - usage.memory_usage_kb, - usage.cpu_percent, - usage.uptime.count(), - monitored_process_.id); -} + bool process_monitor::is_running() const { + std::lock_guard lock(monitor_mutex_); + return running_; + } -void process_monitor::notify_error(process_error error, const std::string& message) { - if (error_callback_) { - try { - error_callback_(monitored_process_, error, message); - } - catch (const std::exception& e) { - log_module_error(PROCESS_MONITOR_LOG_MODULE, "错误回调异常: {}", e.what()); - } - } - - log_module_error(PROCESS_MONITOR_LOG_MODULE, "进程监控错误: {} - {}, 进程ID: {}", - process_error_to_string(error), - message, - monitored_process_.id); -} + void process_monitor::set_monitor_interval(std::chrono::milliseconds interval) { + std::lock_guard lock(monitor_mutex_); + monitor_interval_ = interval; + log_module_debug(PROCESS_MONITOR_LOG_MODULE, "设置监控间隔为 {}ms,进程ID: {}", + interval.count(), monitored_process_.id); + } -} // namespace alicho \ No newline at end of file + void process_monitor::set_state_change_callback(state_change_callback callback) { + std::lock_guard lock(monitor_mutex_); + state_change_callback_ = std::move(callback); + } + + void process_monitor::set_resource_callback(resource_callback callback) { + std::lock_guard lock(monitor_mutex_); + resource_callback_ = std::move(callback); + } + + void process_monitor::set_error_callback(error_callback callback) { + std::lock_guard lock(monitor_mutex_); + error_callback_ = std::move(callback); + } + + void process_monitor::monitor_loop() { + log_module_debug(PROCESS_MONITOR_LOG_MODULE, "监控线程启动,进程ID: {}", + monitored_process_.id); + + while (!stop_requested_) { + try { + update_status(); + } + catch (const std::exception& e) { + log_module_error(PROCESS_MONITOR_LOG_MODULE, "监控循环发生异常: {}", e.what()); + notify_error(process_error::MONITOR_ERROR, e.what()); + + // 出现异常时短暂休眠,避免频繁报错 + std::this_thread::sleep_for(std::chrono::milliseconds(500)); + } + + // 等待直到下一个监控周期或者停止请求 + std::this_thread::sleep_for(monitor_interval_); + } + + log_module_debug(PROCESS_MONITOR_LOG_MODULE, "监控线程退出,进程ID: {}", + monitored_process_.id); + } + + bool process_monitor::check_process_running() { + if (!monitored_process_.process) { + // 进程对象为空,可能尚未启动 + return false; + } + + try { + return monitored_process_.process->running(); + } + catch (const std::exception& e) { + log_module_error(PROCESS_MONITOR_LOG_MODULE, "检查进程运行状态失败: {}", e.what()); + return false; + } + } + + void process_monitor::update_resource_usage() { + try { + process_resource_usage usage; + + // 计算进程运行时间 + auto now = std::chrono::system_clock::now(); + usage.uptime = std::chrono::duration_cast( + now - monitored_process_.start_time); + + #if defined(_WIN32) + if (!monitored_process_.process) { + return; + } + + // 获取进程句柄 + HANDLE process_handle = monitored_process_.process->native_handle(); + if (process_handle == nullptr || process_handle == INVALID_HANDLE_VALUE) { + log_module_error(PROCESS_MONITOR_LOG_MODULE, "无效的进程句柄"); + return; + } + + // 获取内存使用情况 + PROCESS_MEMORY_COUNTERS_EX pmc; + if (GetProcessMemoryInfo(process_handle, (PROCESS_MEMORY_COUNTERS*)&pmc, sizeof(pmc))) { + usage.memory_usage_kb = pmc.WorkingSetSize / 1024; + } + + // 获取CPU使用率 (Windows实现较复杂,这里仅作简化处理) + // 实际应用中可能需要更复杂的计算,这里简单设置为0 + usage.cpu_percent = 0.0; + #elif defined(__linux__) + if (!monitored_process_.process) { + return; + } + + int pid = monitored_process_.process->id(); + + // 读取/proc/{pid}/stat文件获取进程信息 + std::string proc_stat_path = "/proc/" + std::to_string(pid) + "/stat"; + std::ifstream stat_file(proc_stat_path); + if (stat_file.is_open()) { + std::string stat_content; + std::getline(stat_file, stat_content); + + // 解析/proc/{pid}/statm获取内存信息 + std::string proc_statm_path = "/proc/" + std::to_string(pid) + "/statm"; + std::ifstream statm_file(proc_statm_path); + if (statm_file.is_open()) { + long rss; + statm_file >> rss; + + // 转换为KB (页面大小通常为4KB) + usage.memory_usage_kb = rss * 4; + } + + // 简化CPU使用率计算,实际应用需更复杂的处理 + usage.cpu_percent = 0.0; + } + #elif defined(__APPLE__) + // macOS实现,简化处理 + usage.memory_usage_kb = 0; + usage.cpu_percent = 0.0; + #endif + + // 更新进程信息 + monitored_process_.resource_usage = usage; + + // 触发回调 + notify_resource_usage(usage); + } + catch (const std::exception& e) { + log_module_error(PROCESS_MONITOR_LOG_MODULE, "更新资源使用情况失败: {}", e.what()); + notify_error(process_error::MONITOR_ERROR, e.what()); + } + } + + void process_monitor::notify_state_change(process_state new_state) { + if (state_change_callback_) { + try { + state_change_callback_(monitored_process_, new_state); + } + catch (const std::exception& e) { + log_module_error(PROCESS_MONITOR_LOG_MODULE, "状态变化回调异: {}", e.what()); + } + } + + log_module_info(PROCESS_MONITOR_LOG_MODULE, "进程状态变化: {} -> {},进程ID: {}", + process_state_to_string(monitored_process_.state), + process_state_to_string(new_state), + monitored_process_.id); + } + + void process_monitor::notify_resource_usage(const process_resource_usage& usage) { + if (resource_callback_) { + try { + resource_callback_(monitored_process_, usage); + } + catch (const std::exception& e) { + log_module_error(PROCESS_MONITOR_LOG_MODULE, "资源使用回调异常: {}", e.what()); + } + } + + log_module_trace(PROCESS_MONITOR_LOG_MODULE, "进程资源使用: 内存={} KB, CPU={:.2f}%, 运行时间={}ms, 进程ID: {}", + usage.memory_usage_kb, + usage.cpu_percent, + usage.uptime.count(), + monitored_process_.id); + } + + void process_monitor::notify_error(process_error error, const std::string& message) { + if (error_callback_) { + try { + error_callback_(monitored_process_, error, message); + } + catch (const std::exception& e) { + log_module_error(PROCESS_MONITOR_LOG_MODULE, "错误回调异常: {}", e.what()); + } + } + + log_module_error(PROCESS_MONITOR_LOG_MODULE, "进程监控错误: {} - {}, 进程ID: {}", + process_error_to_string(error), + message, + monitored_process_.id); + } +} // namespace alicho diff --git a/src/process_manager/process_monitor.h b/src/process_manager/process_monitor.h index 3f1b2ab..5d1a4fe 100644 --- a/src/process_manager/process_monitor.h +++ b/src/process_manager/process_monitor.h @@ -11,160 +11,158 @@ #include "process_types.h" namespace alicho { + /** + * @brief 进程监控类,用于监控和更新进程状态及资源使用情况 + * + * 该类使用单独的线程定期监控进程状态和资源使用情况,支持设置监控频率和各种回调。 + */ + class process_monitor { + public: + // 状态回调函数类型 + using state_change_callback = std::function; + // 资源使用回调函数类型 + using resource_callback = std::function; + // 错误回调函数类型 + using error_callback = std::function; -/** - * @brief 进程监控类,用于监控和更新进程状态及资源使用情况 - * - * 该类使用单独的线程定期监控进程状态和资源使用情况,支持设置监控频率和各种回调。 - */ -class process_monitor { -public: - // 状态回调函数类型 - using state_change_callback = std::function; - // 资源使用回调函数类型 - using resource_callback = std::function; - // 错误回调函数类型 - using error_callback = std::function; + /** + * @brief 构造函数 + * + * @param process_to_monitor 要监控的进程信息 + * @param monitor_interval 监控间隔,默认为1秒 + */ + explicit process_monitor( + process_info& process_to_monitor, + std::chrono::milliseconds monitor_interval = std::chrono::milliseconds(1000) + ); - /** - * @brief 构造函数 - * - * @param process_to_monitor 要监控的进程信息 - * @param monitor_interval 监控间隔,默认为1秒 - */ - explicit process_monitor( - process_info& process_to_monitor, - std::chrono::milliseconds monitor_interval = std::chrono::milliseconds(1000) - ); + /** + * @brief 析构函,确保停止所有监控活动 + */ + ~process_monitor(); - /** - * @brief 析构函,确保停止所有监控活动 - */ - ~process_monitor(); + // 禁止拷贝构造和拷贝赋值 + process_monitor(const process_monitor&) = delete; + process_monitor& operator=(const process_monitor&) = delete; - // 禁止拷贝构造和拷贝赋值 - process_monitor(const process_monitor&) = delete; - process_monitor& operator=(const process_monitor&) = delete; - - /** - * @brief 启动监控线程 - * - * @return process_error 操作结果 - */ - process_error start(); + /** + * @brief 启动监控线程 + * + * @return process_error 操作结果 + */ + process_error start(); - /** - * @brief 停止监控线程 - * - * @return process_error 操作结果 - */ - process_error stop(); + /** + * @brief 停止监控线程 + * + * @return process_error 操作结果 + */ + process_error stop(); - /** - * @brief 更新进程信息(手动触发更新) - * - * @return process_error 操作结果 - */ - process_error update_status(); + /** + * @brief 更新进程信息(手动触发更新) + * + * @return process_error 操作结果 + */ + process_error update_status(); - /** - * @brief 检查监控器是否正在运行 - * - * @return bool 监控器运行状态 - */ - bool is_running() const; + /** + * @brief 检查监控器是否正在运行 + * + * @return bool 监控器运行状态 + */ + bool is_running() const; - /** - * @brief 设置监控间隔 - * - * @param interval 新的监控间隔 - */ - void set_monitor_interval(std::chrono::milliseconds interval); + /** + * @brief 设置监控间隔 + * + * @param interval 新的监控间隔 + */ + void set_monitor_interval(std::chrono::milliseconds interval); - /** - * @brief 设置状态变化回调 - * - * @param callback 状态变化时的回调函数 - */ - void set_state_change_callback(state_change_callback callback); + /** + * @brief 设置状态变化回调 + * + * @param callback 状态变化时的回调函数 + */ + void set_state_change_callback(state_change_callback callback); - /** - * @brief 设置资源使用回调 - * - * @param callback 资源使用更新时的回调函数 - */ - void set_resource_callback(resource_callback callback); + /** + * @brief 设置资源使用回调 + * + * @param callback 资源使用更新时的回调函数 + */ + void set_resource_callback(resource_callback callback); - /** - * @brief 设置错误回调 - * - * @param callback 发生错误时的回调函数 - */ - void set_error_callback(error_callback callback); + /** + * @brief 设置错误回调 + * + * @param callback 发生错误时的回调函数 + */ + void set_error_callback(error_callback callback); -private: - /** - * @brief 监控线程的主循环函数 - */ - void monitor_loop(); + private: + /** + * @brief 监控线程的主循环函数 + */ + void monitor_loop(); - /** - * @brief 检查进程是否仍在运行 - * - * @return bool 进程运行状态 - */ - bool check_process_running(); + /** + * @brief 检查进程是否仍在运行 + * + * @return bool 进程运行状态 + */ + bool check_process_running(); - /** - * @brief 更新进程资源使用信息 - */ - void update_resource_usage(); + /** + * @brief 更新进程资源使用信息 + */ + void update_resource_usage(); - /** - * @brief 通知状态变化 - * - * @param new_state 新状态 - */ - void notify_state_change(process_state new_state); + /** + * @brief 通知状态变化 + * + * @param new_state 新状态 + */ + void notify_state_change(process_state new_state); - /** - * @brief 通知资源使用变化 - * - * @param usage 最新的资源使用情况 - */ - void notify_resource_usage(const process_resource_usage& usage); + /** + * @brief 通知资源使用变化 + * + * @param usage 最新的资源使用情况 + */ + void notify_resource_usage(const process_resource_usage& usage); - /** - * @brief 通知错误 - * - * @param error 错误类型 - * @param message 错误消息 - */ - void notify_error(process_error error, const std::string& message); + /** + * @brief 通知错误 + * + * @param error 错误类型 + * @param message 错误消息 + */ + void notify_error(process_error error, const std::string& message); -private: - // 被监控的进程信息 - process_info& monitored_process_; - - // 监控线程 - std::unique_ptr monitor_thread_; - - // 监控间隔 - std::chrono::milliseconds monitor_interval_; - - // 监控器运行状态标志 - std::atomic running_; - - // 监控器停止标志 - std::atomic stop_requested_; - - // 同步互斥量 - mutable std::mutex monitor_mutex_; - - // 回调函数 - state_change_callback state_change_callback_; - resource_callback resource_callback_; - error_callback error_callback_; -}; + private: + // 被监控的进程信息 + process_info& monitored_process_; -} // namespace alicho \ No newline at end of file + // 监控线程 + std::unique_ptr monitor_thread_; + + // 监控间隔 + std::chrono::milliseconds monitor_interval_; + + // 监控器运行状态标志 + std::atomic running_; + + // 监控器停止标志 + std::atomic stop_requested_; + + // 同步互斥量 + mutable std::mutex monitor_mutex_; + + // 回调函数 + state_change_callback state_change_callback_; + resource_callback resource_callback_; + error_callback error_callback_; + }; +} // namespace alicho diff --git a/src/process_manager/process_types.h b/src/process_manager/process_types.h index 3c5c8fe..e80cbc0 100644 --- a/src/process_manager/process_types.h +++ b/src/process_manager/process_types.h @@ -10,113 +10,130 @@ namespace alicho { + // 进程状态枚举 + enum class process_state { + UNKNOWN, + STARTING, // 正在启动 + RUNNING, // 运行中 + STOPPED, // 已停止 + FAILED // 启动或运行失败 + }; -// 进程状态枚举 -enum class process_state { - UNKNOWN, - STARTING, // 正在启动 - RUNNING, // 运行中 - STOPPED, // 已停止 - FAILED // 启动或运行失败 -}; + // 沙箱类型枚举 + enum class sandbox_type { + HOST, // 主机沙箱 + PLUGIN, // 插件沙箱 + CUSTOM // 自定义沙箱 + }; -// 沙箱类型枚举 -enum class sandbox_type { - HOST, // 主机沙箱 - PLUGIN, // 插件沙箱 - CUSTOM // 自定义沙箱 -}; + // 进程错误枚举 + enum class process_error { + SUCCESS, + PROCESS_ALREADY_RUNNING, + PROCESS_NOT_RUNNING, + LAUNCH_FAILED, + TERMINATE_FAILED, + MONITOR_ERROR, + TIMEOUT, + UNKNOWN_ERROR + }; -// 进程错误枚举 -enum class process_error { - SUCCESS, - PROCESS_ALREADY_RUNNING, - PROCESS_NOT_RUNNING, - LAUNCH_FAILED, - TERMINATE_FAILED, - MONITOR_ERROR, - TIMEOUT, - UNKNOWN_ERROR -}; + // 进程资源使用信息 + struct process_resource_usage { + double cpu_percent{0.0}; // CPU使用百分比 + std::size_t memory_usage_kb{0}; // 内存使用(KB) + std::chrono::milliseconds uptime{0}; // 运行时间 + }; -// 进程资源使用信息 -struct process_resource_usage { - double cpu_percent{0.0}; // CPU使用百分比 - std::size_t memory_usage_kb{0}; // 内存使用(KB) - std::chrono::milliseconds uptime{0}; // 运行时间 -}; + // 进程信息结构体 + struct process_info { + uint32_t id{0}; // 进程唯一ID + std::string name; // 进程名称 + std::string executable_path; // 可执行文件路径 + std::vector arguments; // 命令行参数 + sandbox_type type{sandbox_type::HOST}; // 沙箱类型 + process_state state{process_state::UNKNOWN}; // 当前状态 + process_resource_usage resource_usage; // 资源使用情况 + std::unique_ptr process; // Boost.Process子进程对象(boost 1.89.0) + std::chrono::system_clock::time_point start_time; // 启动时间 + int exit_code{0}; // 退出码(如果已退出) + std::string error_message; // 错误信息(如果有) -// 进程信息结构体 -struct process_info { - uint32_t id{0}; // 进程唯一ID - std::string name; // 进程名称 - std::string executable_path; // 可执行文件路径 - std::vector arguments; // 命令行参数 - sandbox_type type{sandbox_type::HOST}; // 沙箱类型 - process_state state{process_state::UNKNOWN}; // 当前状态 - process_resource_usage resource_usage; // 资源使用情况 - std::unique_ptr process; // Boost.Process子进程对象(boost 1.89.0) - std::chrono::system_clock::time_point start_time; // 启动时间 - int exit_code{0}; // 退出码(如果已退出) - std::string error_message; // 错误信息(如果有) - - // 默认构造函数 - process_info() = default; - - // 带参数的构造函数 - process_info(uint32_t process_id, - const std::string& process_name, - const std::string& path, - const std::vector& args, - sandbox_type sandbox_type = sandbox_type::HOST) - : id(process_id), - name(process_name), - executable_path(path), - arguments(args), - type(sandbox_type), - state(process_state::UNKNOWN) {} - - // 检查进程是否在运行 - bool is_running() const { - return state == process_state::RUNNING || state == process_state::STARTING; - } -}; + // 默认构造函数 + process_info() = default; -// 辅助函数:获取进程状态的字符串表示 -inline std::string process_state_to_string(process_state state) { - switch (state) { - case process_state::UNKNOWN: return "UNKNOWN"; - case process_state::STARTING: return "STARTING"; - case process_state::RUNNING: return "RUNNING"; - case process_state::STOPPED: return "STOPPED"; - case process_state::FAILED: return "FAILED"; - default: return "INVALID_STATE"; - } -} + // 带参数的构造函数 + process_info(uint32_t process_id, + const std::string& process_name, + const std::string& path, + const std::vector& args, + sandbox_type sandbox_type = sandbox_type::HOST) : id(process_id), + name(process_name), + executable_path(path), + arguments(args), + type(sandbox_type), + state(process_state::UNKNOWN) { + } -// 辅助函数:获取沙箱类型的字符串表示 -inline std::string sandbox_type_to_string(sandbox_type type) { - switch (type) { - case sandbox_type::HOST: return "HOST"; - case sandbox_type::PLUGIN: return "PLUGIN"; - case sandbox_type::CUSTOM: return "CUSTOM"; - default: return "INVALID_TYPE"; - } -} + // 检查进程是否在运行 + bool is_running() const { + return state == process_state::RUNNING || state == process_state::STARTING; + } + }; -// 辅助函数:获取进程错误的字符串表示 -inline std::string process_error_to_string(process_error error) { - switch (error) { - case process_error::SUCCESS: return "SUCCESS"; - case process_error::PROCESS_ALREADY_RUNNING: return "PROCESS_ALREADY_RUNNING"; - case process_error::PROCESS_NOT_RUNNING: return "PROCESS_NOT_RUNNING"; - case process_error::LAUNCH_FAILED: return "LAUNCH_FAILED"; - case process_error::TERMINATE_FAILED: return "TERMINATE_FAILED"; - case process_error::MONITOR_ERROR: return "MONITOR_ERROR"; - case process_error::TIMEOUT: return "TIMEOUT"; - case process_error::UNKNOWN_ERROR: return "UNKNOWN_ERROR"; - default: return "INVALID_ERROR"; - } -} + // 辅助函数:获取进程状态的字符串表示 + inline std::string process_state_to_string(process_state state) { + switch (state) { + case process_state::UNKNOWN: + return "UNKNOWN"; + case process_state::STARTING: + return "STARTING"; + case process_state::RUNNING: + return "RUNNING"; + case process_state::STOPPED: + return "STOPPED"; + case process_state::FAILED: + return "FAILED"; + default: + return "INVALID_STATE"; + } + } -} // namespace alicho \ No newline at end of file + // 辅助函数:获取沙箱类型的字符串表示 + inline std::string sandbox_type_to_string(sandbox_type type) { + switch (type) { + case sandbox_type::HOST: + return "HOST"; + case sandbox_type::PLUGIN: + return "PLUGIN"; + case sandbox_type::CUSTOM: + return "CUSTOM"; + default: + return "INVALID_TYPE"; + } + } + + // 辅助函数:获取进程错误的字符串表示 + inline std::string process_error_to_string(process_error error) { + switch (error) { + case process_error::SUCCESS: + return "SUCCESS"; + case process_error::PROCESS_ALREADY_RUNNING: + return "PROCESS_ALREADY_RUNNING"; + case process_error::PROCESS_NOT_RUNNING: + return "PROCESS_NOT_RUNNING"; + case process_error::LAUNCH_FAILED: + return "LAUNCH_FAILED"; + case process_error::TERMINATE_FAILED: + return "TERMINATE_FAILED"; + case process_error::MONITOR_ERROR: + return "MONITOR_ERROR"; + case process_error::TIMEOUT: + return "TIMEOUT"; + case process_error::UNKNOWN_ERROR: + return "UNKNOWN_ERROR"; + default: + return "INVALID_ERROR"; + } + } +} // namespace alicho diff --git a/tests/process_manager/test_process_manager.cpp b/tests/process_manager/test_process_manager.cpp index f570dd5..f06b762 100644 --- a/tests/process_manager/test_process_manager.cpp +++ b/tests/process_manager/test_process_manager.cpp @@ -18,39 +18,40 @@ using namespace alicho; // 回调计数器,用于跟踪回调函数的调用 struct callback_counter { - std::atomic state_change_count{0}; - std::atomic resource_update_count{0}; - std::atomic error_count{0}; - - std::mutex mutex; - std::condition_variable cv; - - process_state last_state{process_state::UNKNOWN}; - process_error last_error{process_error::SUCCESS}; - std::string last_error_message; - - void reset() { - state_change_count = 0; - resource_update_count = 0; - error_count = 0; - last_state = process_state::UNKNOWN; - last_error = process_error::SUCCESS; - last_error_message.clear(); - } - - bool wait_for_state_change(int expected_count, std::chrono::milliseconds timeout = std::chrono::milliseconds(5000)) { - std::unique_lock lock(mutex); - return cv.wait_for(lock, timeout, [this, expected_count]() { - return state_change_count >= expected_count; - }); - } - - bool wait_for_error(int expected_count, std::chrono::milliseconds timeout = std::chrono::milliseconds(5000)) { - std::unique_lock lock(mutex); - return cv.wait_for(lock, timeout, [this, expected_count]() { - return error_count >= expected_count; - }); - } + std::atomic state_change_count{0}; + std::atomic resource_update_count{0}; + std::atomic error_count{0}; + + std::mutex mutex; + std::condition_variable cv; + + process_state last_state{process_state::UNKNOWN}; + process_error last_error{process_error::SUCCESS}; + std::string last_error_message; + + void reset() { + state_change_count = 0; + resource_update_count = 0; + error_count = 0; + last_state = process_state::UNKNOWN; + last_error = process_error::SUCCESS; + last_error_message.clear(); + } + + bool wait_for_state_change(int expected_count, + std::chrono::milliseconds timeout = std::chrono::milliseconds(5000)) { + std::unique_lock lock(mutex); + return cv.wait_for(lock, timeout, [this, expected_count]() { + return state_change_count >= expected_count; + }); + } + + bool wait_for_error(int expected_count, std::chrono::milliseconds timeout = std::chrono::milliseconds(5000)) { + std::unique_lock lock(mutex); + return cv.wait_for(lock, timeout, [this, expected_count]() { + return error_count >= expected_count; + }); + } }; // 全局回调计数器 @@ -58,74 +59,74 @@ static callback_counter g_callback_counter; // 回调函数 void state_change_callback(const process_info& info, process_state new_state) { - std::lock_guard lock(g_callback_counter.mutex); - g_callback_counter.state_change_count++; - g_callback_counter.last_state = new_state; - g_callback_counter.cv.notify_all(); + std::lock_guard lock(g_callback_counter.mutex); + g_callback_counter.state_change_count++; + g_callback_counter.last_state = new_state; + g_callback_counter.cv.notify_all(); } void resource_callback(const process_info& info, const process_resource_usage& usage) { - std::lock_guard lock(g_callback_counter.mutex); - g_callback_counter.resource_update_count++; - g_callback_counter.cv.notify_all(); + std::lock_guard lock(g_callback_counter.mutex); + g_callback_counter.resource_update_count++; + g_callback_counter.cv.notify_all(); } void error_callback(const process_info& info, process_error error, const std::string& message) { - std::lock_guard lock(g_callback_counter.mutex); - g_callback_counter.error_count++; - g_callback_counter.last_error = error; - g_callback_counter.last_error_message = message; - g_callback_counter.cv.notify_all(); + std::lock_guard lock(g_callback_counter.mutex); + g_callback_counter.error_count++; + g_callback_counter.last_error = error; + g_callback_counter.last_error_message = message; + g_callback_counter.cv.notify_all(); } // 创建一个简单的测试可执行文件 std::string create_test_executable() { - std::string exe_path; - -#ifdef _WIN32 - exe_path = "test_process.bat"; - std::ofstream bat_file(exe_path); - bat_file << "@echo off\n"; - bat_file << "ping 127.0.0.1 -n 6 > nul\n"; // 运行约5秒,给监控器足够时间 - bat_file << "exit /b 0\n"; - bat_file.close(); -#else - exe_path = "./test_process.sh"; - std::ofstream script_file(exe_path); - script_file << "#!/bin/bash\n"; - script_file << "sleep 5\n"; // 运行5秒然后退出 - script_file << "exit 0\n"; - script_file.close(); - - // 设置执行权限 - std::filesystem::permissions(exe_path, std::filesystem::perms::owner_exec, std::filesystem::perm_options::add); -#endif - - return exe_path; + std::string exe_path; + + #ifdef _WIN32 + exe_path = "test_process.bat"; + std::ofstream bat_file(exe_path); + bat_file << "@echo off\n"; + bat_file << "ping 127.0.0.1 -n 6 > nul\n"; // 运行约5秒,给监控器足够时间 + bat_file << "exit /b 0\n"; + bat_file.close(); + #else + exe_path = "./test_process.sh"; + std::ofstream script_file(exe_path); + script_file << "#!/bin/bash\n"; + script_file << "sleep 5\n"; // 运行5秒然后退出 + script_file << "exit 0\n"; + script_file.close(); + + // 设置执行权限 + std::filesystem::permissions(exe_path, std::filesystem::perms::owner_exec, std::filesystem::perm_options::add); + #endif + + return exe_path; } // 创建一个立即失败的测试可执行文件 std::string create_failing_executable() { - std::string exe_path; - -#ifdef _WIN32 - exe_path = "test_fail_process.bat"; - std::ofstream bat_file(exe_path); - bat_file << "@echo off\n"; - bat_file << "exit /b 1\n"; // 立即以错误码退出 - bat_file.close(); -#else - exe_path = "./test_fail_process.sh"; - std::ofstream script_file(exe_path); - script_file << "#!/bin/bash\n"; - script_file << "exit 1\n"; // 立即以错误码退出 - script_file.close(); - - // 设置执行权限 - std::filesystem::permissions(exe_path, std::filesystem::perms::owner_exec, std::filesystem::perm_options::add); -#endif - - return exe_path; + std::string exe_path; + + #ifdef _WIN32 + exe_path = "test_fail_process.bat"; + std::ofstream bat_file(exe_path); + bat_file << "@echo off\n"; + bat_file << "exit /b 1\n"; // 立即以错误码退出 + bat_file.close(); + #else + exe_path = "./test_fail_process.sh"; + std::ofstream script_file(exe_path); + script_file << "#!/bin/bash\n"; + script_file << "exit 1\n"; // 立即以错误码退出 + script_file.close(); + + // 设置执行权限 + std::filesystem::permissions(exe_path, std::filesystem::perms::owner_exec, std::filesystem::perm_options::add); + #endif + + return exe_path; } // ============================================================================ @@ -134,222 +135,223 @@ std::string create_failing_executable() { class ProcessManagerTest : public ::testing::Test { protected: - void SetUp() override { - // 重置回调计数器 - g_callback_counter.reset(); - - // 设置回调函数 - auto& manager = process_manager::instance(); - manager.set_state_change_callback(state_change_callback); - manager.set_resource_callback(resource_callback); - manager.set_error_callback(error_callback); - - // 创建测试可执行文件 - test_executable_ = create_test_executable(); - failing_executable_ = create_failing_executable(); - } - - void TearDown() override { - // 终止所有进程 - auto& manager = process_manager::instance(); - manager.terminate_all_processes(true); - - // 清理测试文件 - try { - if (std::filesystem::exists(test_executable_)) { - std::filesystem::remove(test_executable_); - } - if (std::filesystem::exists(failing_executable_)) { - std::filesystem::remove(failing_executable_); - } - } catch (...) { - // 忽略清理错误 - } - } - - std::string test_executable_; - std::string failing_executable_; + void SetUp() override { + // 重置回调计数器 + g_callback_counter.reset(); + + // 设置回调函数 + auto& manager = process_manager::instance(); + manager.set_state_change_callback(state_change_callback); + manager.set_resource_callback(resource_callback); + manager.set_error_callback(error_callback); + + // 创建测试可执行文件 + test_executable_ = create_test_executable(); + failing_executable_ = create_failing_executable(); + } + + void TearDown() override { + // 终止所有进程 + auto& manager = process_manager::instance(); + manager.terminate_all_processes(true); + + // 清理测试文件 + try { + if (std::filesystem::exists(test_executable_)) { + std::filesystem::remove(test_executable_); + } + if (std::filesystem::exists(failing_executable_)) { + std::filesystem::remove(failing_executable_); + } + } + catch (...) { + // 忽略清理错误 + } + } + + std::string test_executable_; + std::string failing_executable_; }; /** * @brief 测试单例模式正常工作 */ TEST_F(ProcessManagerTest, SingletonPattern) { - auto& manager1 = process_manager::instance(); - auto& manager2 = process_manager::instance(); - - // 应该是同一个实例 - EXPECT_EQ(&manager1, &manager2); - - // 初始状态应该是0个进程 - EXPECT_EQ(manager1.process_count(), 0); + auto& manager1 = process_manager::instance(); + auto& manager2 = process_manager::instance(); + + // 应该是同一个实例 + EXPECT_EQ(&manager1, &manager2); + + // 初始状态应该是0个进程 + EXPECT_EQ(manager1.process_count(), 0); } /** * @brief 测试进程启动功能 */ TEST_F(ProcessManagerTest, LaunchProcess) { - auto& manager = process_manager::instance(); - - // 启动一个简单的进程 - uint32_t process_id = manager.launch_process( - "test_process", - test_executable_, - {}, - sandbox_type::HOST, - true // 启用监控 - ); - - EXPECT_NE(process_id, 0); // 应该返回有效的进程ID - - // 检查进程是否被添加到管理列表 - EXPECT_TRUE(manager.has_process(process_id)); - EXPECT_EQ(manager.process_count(), 1); - - // 检查进程信息 - const process_info* info = manager.get_process_info(process_id); - ASSERT_NE(info, nullptr); - EXPECT_EQ(info->name, "test_process"); - EXPECT_EQ(info->executable_path, test_executable_); - EXPECT_EQ(info->type, sandbox_type::HOST); - - // 等待进程开始运行 - std::this_thread::sleep_for(std::chrono::milliseconds(100)); - - // 检查进程是否在运行 - EXPECT_TRUE(manager.is_process_running(process_id)); - - // 终止进程 - auto result = manager.terminate_process(process_id); - EXPECT_EQ(result, process_error::SUCCESS); + auto& manager = process_manager::instance(); + + // 启动一个简单的进程 + uint32_t process_id = manager.launch_process( + "test_process", + test_executable_, + {}, + sandbox_type::HOST, + true // 启用监控 + ); + + EXPECT_NE(process_id, 0); // 应该返回有效的进程ID + + // 检查进程是否被添加到管理列表 + EXPECT_TRUE(manager.has_process(process_id)); + EXPECT_EQ(manager.process_count(), 1); + + // 检查进程信息 + const process_info* info = manager.get_process_info(process_id); + ASSERT_NE(info, nullptr); + EXPECT_EQ(info->name, "test_process"); + EXPECT_EQ(info->executable_path, test_executable_); + EXPECT_EQ(info->type, sandbox_type::HOST); + + // 等待进程开始运行 + std::this_thread::sleep_for(std::chrono::milliseconds(100)); + + // 检查进程是否在运行 + EXPECT_TRUE(manager.is_process_running(process_id)); + + // 终止进程 + auto result = manager.terminate_process(process_id); + EXPECT_EQ(result, process_error::SUCCESS); } /** * @brief 测试进程终止功能 */ TEST_F(ProcessManagerTest, TerminateProcess) { - auto& manager = process_manager::instance(); - - // 启动进程 - uint32_t process_id = manager.launch_process( - "test_process_terminate", - test_executable_, - {}, - sandbox_type::HOST, - false // 不启用监控,简化测试 - ); - - ASSERT_NE(process_id, 0); - - // 等待进程启动 - std::this_thread::sleep_for(std::chrono::milliseconds(100)); - - // 正常终止进程 - auto result = manager.terminate_process(process_id, false); - EXPECT_EQ(result, process_error::SUCCESS); - - // 检查进程是否已停止 - EXPECT_FALSE(manager.is_process_running(process_id)); + auto& manager = process_manager::instance(); + + // 启动进程 + uint32_t process_id = manager.launch_process( + "test_process_terminate", + test_executable_, + {}, + sandbox_type::HOST, + false // 不启用监控,简化测试 + ); + + ASSERT_NE(process_id, 0); + + // 等待进程启动 + std::this_thread::sleep_for(std::chrono::milliseconds(100)); + + // 正常终止进程 + auto result = manager.terminate_process(process_id, false); + EXPECT_EQ(result, process_error::SUCCESS); + + // 检查进程是否已停止 + EXPECT_FALSE(manager.is_process_running(process_id)); } /** * @brief 测试强制终止进程 */ TEST_F(ProcessManagerTest, ForceTerminateProcess) { - auto& manager = process_manager::instance(); - - // 启动进程 - uint32_t process_id = manager.launch_process( - "test_process_force_terminate", - test_executable_, - {}, - sandbox_type::HOST, - false - ); - - ASSERT_NE(process_id, 0); - - // 等待进程启动 - std::this_thread::sleep_for(std::chrono::milliseconds(100)); - - // 强制终止进程 - auto result = manager.terminate_process(process_id, true); - EXPECT_EQ(result, process_error::SUCCESS); - - // 检查进程是否已停止 - EXPECT_FALSE(manager.is_process_running(process_id)); + auto& manager = process_manager::instance(); + + // 启动进程 + uint32_t process_id = manager.launch_process( + "test_process_force_terminate", + test_executable_, + {}, + sandbox_type::HOST, + false + ); + + ASSERT_NE(process_id, 0); + + // 等待进程启动 + std::this_thread::sleep_for(std::chrono::milliseconds(100)); + + // 强制终止进程 + auto result = manager.terminate_process(process_id, true); + EXPECT_EQ(result, process_error::SUCCESS); + + // 检查进程是否已停止 + EXPECT_FALSE(manager.is_process_running(process_id)); } /** * @brief 测试终止所有进程 */ TEST_F(ProcessManagerTest, TerminateAllProcesses) { - auto& manager = process_manager::instance(); - - // 启动多个进程 - std::vector process_ids; - for (int i = 0; i < 3; ++i) { - uint32_t process_id = manager.launch_process( - "test_process_" + std::to_string(i), - test_executable_, - {}, - sandbox_type::HOST, - false - ); - if (process_id != 0) { - process_ids.push_back(process_id); - } - } - - EXPECT_GT(process_ids.size(), 0); - EXPECT_EQ(manager.process_count(), process_ids.size()); - - // 等待进程启动 - std::this_thread::sleep_for(std::chrono::milliseconds(200)); - - // 终止所有进程 - auto result = manager.terminate_all_processes(); - EXPECT_EQ(result, process_error::SUCCESS); - - // 检查所有进程是否已停止 - for (uint32_t process_id : process_ids) { - EXPECT_FALSE(manager.is_process_running(process_id)); - } + auto& manager = process_manager::instance(); + + // 启动多个进程 + std::vector process_ids; + for (int i = 0; i < 3; ++i) { + uint32_t process_id = manager.launch_process( + "test_process_" + std::to_string(i), + test_executable_, + {}, + sandbox_type::HOST, + false + ); + if (process_id != 0) { + process_ids.push_back(process_id); + } + } + + EXPECT_GT(process_ids.size(), 0); + EXPECT_EQ(manager.process_count(), process_ids.size()); + + // 等待进程启动 + std::this_thread::sleep_for(std::chrono::milliseconds(200)); + + // 终止所有进程 + auto result = manager.terminate_all_processes(); + EXPECT_EQ(result, process_error::SUCCESS); + + // 检查所有进程是否已停止 + for (uint32_t process_id : process_ids) { + EXPECT_FALSE(manager.is_process_running(process_id)); + } } /** * @brief 测试获取进程ID列表 */ TEST_F(ProcessManagerTest, GetAllProcessIds) { - auto& manager = process_manager::instance(); - - // 初始应该没有进程 - auto initial_ids = manager.get_all_process_ids(); - EXPECT_TRUE(initial_ids.empty()); - - // 启动几个进程 - std::vector launched_ids; - for (int i = 0; i < 2; ++i) { - uint32_t process_id = manager.launch_process( - "test_process_list_" + std::to_string(i), - test_executable_, - {}, - sandbox_type::HOST, - false - ); - if (process_id != 0) { - launched_ids.push_back(process_id); - } - } - - // 获取进程ID列表 - auto current_ids = manager.get_all_process_ids(); - EXPECT_EQ(current_ids.size(), launched_ids.size()); - - // 验证ID列表是否包含所有已启动的进程 - for (uint32_t launched_id : launched_ids) { - EXPECT_TRUE(std::find(current_ids.begin(), current_ids.end(), launched_id) != current_ids.end()); - } + auto& manager = process_manager::instance(); + + // 初始应该没有进程 + auto initial_ids = manager.get_all_process_ids(); + EXPECT_TRUE(initial_ids.empty()); + + // 启动几个进程 + std::vector launched_ids; + for (int i = 0; i < 2; ++i) { + uint32_t process_id = manager.launch_process( + "test_process_list_" + std::to_string(i), + test_executable_, + {}, + sandbox_type::HOST, + false + ); + if (process_id != 0) { + launched_ids.push_back(process_id); + } + } + + // 获取进程ID列表 + auto current_ids = manager.get_all_process_ids(); + EXPECT_EQ(current_ids.size(), launched_ids.size()); + + // 验证ID列表是否包含所有已启动的进程 + for (uint32_t launched_id : launched_ids) { + EXPECT_TRUE(std::find(current_ids.begin(), current_ids.end(), launched_id) != current_ids.end()); + } } // ============================================================================ @@ -360,82 +362,82 @@ TEST_F(ProcessManagerTest, GetAllProcessIds) { * @brief 测试启动不存在的可执行文件 */ TEST_F(ProcessManagerTest, LaunchNonExistentExecutable) { - auto& manager = process_manager::instance(); - - // 尝试启动不存在的可执行文件 - uint32_t process_id = manager.launch_process( - "non_existent_process", - "non_existent_executable.exe", - {}, - sandbox_type::HOST, - false - ); - - // 应该返回0表示失败 - EXPECT_EQ(process_id, 0); - - // 进程计数应该没有增加 - EXPECT_EQ(manager.process_count(), 0); + auto& manager = process_manager::instance(); + + // 尝试启动不存在的可执行文件 + uint32_t process_id = manager.launch_process( + "non_existent_process", + "non_existent_executable.exe", + {}, + sandbox_type::HOST, + false + ); + + // 应该返回0表示失败 + EXPECT_EQ(process_id, 0); + + // 进程计数应该没有增加 + EXPECT_EQ(manager.process_count(), 0); } /** * @brief 测试终止不存在的进程 */ TEST_F(ProcessManagerTest, TerminateNonExistentProcess) { - auto& manager = process_manager::instance(); - - // 尝试终止不存在的进程 - uint32_t fake_process_id = 99999; - auto result = manager.terminate_process(fake_process_id); - - EXPECT_EQ(result, process_error::PROCESS_NOT_RUNNING); + auto& manager = process_manager::instance(); + + // 尝试终止不存在的进程 + uint32_t fake_process_id = 99999; + auto result = manager.terminate_process(fake_process_id); + + EXPECT_EQ(result, process_error::PROCESS_NOT_RUNNING); } /** * @brief 测试重复终止已终止的进程 */ TEST_F(ProcessManagerTest, TerminateAlreadyTerminatedProcess) { - auto& manager = process_manager::instance(); - - // 启动进程 - uint32_t process_id = manager.launch_process( - "test_process_double_terminate", - test_executable_, - {}, - sandbox_type::HOST, - false - ); - - ASSERT_NE(process_id, 0); - - // 等待进程启动 - std::this_thread::sleep_for(std::chrono::milliseconds(100)); - - // 第一次终止 - auto result1 = manager.terminate_process(process_id); - EXPECT_EQ(result1, process_error::SUCCESS); - - // 等待进程真正停止 - std::this_thread::sleep_for(std::chrono::milliseconds(100)); - - // 第二次终止同一个进程 - auto result2 = manager.terminate_process(process_id); - EXPECT_EQ(result2, process_error::PROCESS_NOT_RUNNING); + auto& manager = process_manager::instance(); + + // 启动进程 + uint32_t process_id = manager.launch_process( + "test_process_double_terminate", + test_executable_, + {}, + sandbox_type::HOST, + false + ); + + ASSERT_NE(process_id, 0); + + // 等待进程启动 + std::this_thread::sleep_for(std::chrono::milliseconds(100)); + + // 第一次终止 + auto result1 = manager.terminate_process(process_id); + EXPECT_EQ(result1, process_error::SUCCESS); + + // 等待进程真正停止 + std::this_thread::sleep_for(std::chrono::milliseconds(100)); + + // 第二次终止同一个进程 + auto result2 = manager.terminate_process(process_id); + EXPECT_EQ(result2, process_error::PROCESS_NOT_RUNNING); } /** * @brief 测试查询不存在进程的信息 */ TEST_F(ProcessManagerTest, GetNonExistentProcessInfo) { - auto& manager = process_manager::instance(); - - // 查询不存在的进程信息 - uint32_t fake_process_id = 88888; - const process_info* info = manager.get_process_info(fake_process_id); - - EXPECT_EQ(info, nullptr); - EXPECT_FALSE(manager.has_process(fake_process_id)); - EXPECT_FALSE(manager.is_process_running(fake_process_id)); + auto& manager = process_manager::instance(); + + // 查询不存在的进程信息 + uint32_t fake_process_id = 88888; + const process_info* info = manager.get_process_info(fake_process_id); + + EXPECT_EQ(info, nullptr); + EXPECT_FALSE(manager.has_process(fake_process_id)); + EXPECT_FALSE(manager.is_process_running(fake_process_id)); } // ============================================================================ @@ -446,37 +448,37 @@ TEST_F(ProcessManagerTest, GetNonExistentProcessInfo) { * @brief 测试不同沙箱类型的进程 */ TEST_F(ProcessManagerTest, DifferentSandboxTypes) { - auto& manager = process_manager::instance(); - - // 测试不同的沙箱类型 - std::vector sandbox_types = { - sandbox_type::HOST, - sandbox_type::PLUGIN, - sandbox_type::CUSTOM - }; - - std::vector process_ids; - - for (auto type : sandbox_types) { - uint32_t process_id = manager.launch_process( - "test_sandbox_" + sandbox_type_to_string(type), - test_executable_, - {}, - type, - false - ); - - if (process_id != 0) { - process_ids.push_back(process_id); - - // 验证沙箱类型 - const process_info* info = manager.get_process_info(process_id); - ASSERT_NE(info, nullptr); - EXPECT_EQ(info->type, type); - } - } - - EXPECT_GT(process_ids.size(), 0); + auto& manager = process_manager::instance(); + + // 测试不同的沙箱类型 + std::vector sandbox_types = { + sandbox_type::HOST, + sandbox_type::PLUGIN, + sandbox_type::CUSTOM + }; + + std::vector process_ids; + + for (auto type : sandbox_types) { + uint32_t process_id = manager.launch_process( + "test_sandbox_" + sandbox_type_to_string(type), + test_executable_, + {}, + type, + false + ); + + if (process_id != 0) { + process_ids.push_back(process_id); + + // 验证沙箱类型 + const process_info* info = manager.get_process_info(process_id); + ASSERT_NE(info, nullptr); + EXPECT_EQ(info->type, type); + } + } + + EXPECT_GT(process_ids.size(), 0); } // ============================================================================ @@ -487,62 +489,62 @@ TEST_F(ProcessManagerTest, DifferentSandboxTypes) { * @brief 测试进程状态监控回调 */ TEST_F(ProcessManagerTest, ProcessStateMonitoring) { - auto& manager = process_manager::instance(); - - // 启动进程并启用监控 - uint32_t process_id = manager.launch_process( - "test_process_monitoring", - test_executable_, - {}, - sandbox_type::HOST, - true // 启用监控 - ); - - ASSERT_NE(process_id, 0); - - // 等待状态变化回调 - EXPECT_TRUE(g_callback_counter.wait_for_state_change(1, std::chrono::milliseconds(3000))); - - // 等待进程运行一段时间 - std::this_thread::sleep_for(std::chrono::milliseconds(500)); - - // 终止进程 - auto result = manager.terminate_process(process_id); - EXPECT_EQ(result, process_error::SUCCESS); - - // 等待更多状态变化 - std::this_thread::sleep_for(std::chrono::milliseconds(500)); - - // 验证收到了回调 - EXPECT_GT(g_callback_counter.state_change_count.load(), 0); + auto& manager = process_manager::instance(); + + // 启动进程并启用监控 + uint32_t process_id = manager.launch_process( + "test_process_monitoring", + test_executable_, + {}, + sandbox_type::HOST, + true // 启用监控 + ); + + ASSERT_NE(process_id, 0); + + // 等待状态变化回调 + EXPECT_TRUE(g_callback_counter.wait_for_state_change(1, std::chrono::milliseconds(3000))); + + // 等待进程运行一段时间 + std::this_thread::sleep_for(std::chrono::milliseconds(500)); + + // 终止进程 + auto result = manager.terminate_process(process_id); + EXPECT_EQ(result, process_error::SUCCESS); + + // 等待更多状态变化 + std::this_thread::sleep_for(std::chrono::milliseconds(500)); + + // 验证收到了回调 + EXPECT_GT(g_callback_counter.state_change_count.load(), 0); } /** * @brief 测试参数传递 */ TEST_F(ProcessManagerTest, ProcessArguments) { - auto& manager = process_manager::instance(); - - // 传递参数 - std::vector arguments = {"arg1", "arg2", "arg3"}; - - uint32_t process_id = manager.launch_process( - "test_process_args", - test_executable_, - arguments, - sandbox_type::HOST, - false - ); - - if (process_id != 0) { - // 验证参数是否正确保存 - const process_info* info = manager.get_process_info(process_id); - ASSERT_NE(info, nullptr); - EXPECT_EQ(info->arguments, arguments); - - // 清理 - manager.terminate_process(process_id); - } + auto& manager = process_manager::instance(); + + // 传递参数 + std::vector arguments = {"arg1", "arg2", "arg3"}; + + uint32_t process_id = manager.launch_process( + "test_process_args", + test_executable_, + arguments, + sandbox_type::HOST, + false + ); + + if (process_id != 0) { + // 验证参数是否正确保存 + const process_info* info = manager.get_process_info(process_id); + ASSERT_NE(info, nullptr); + EXPECT_EQ(info->arguments, arguments); + + // 清理 + manager.terminate_process(process_id); + } } // ============================================================================ @@ -550,6 +552,6 @@ TEST_F(ProcessManagerTest, ProcessArguments) { // ============================================================================ int main(int argc, char** argv) { - ::testing::InitGoogleTest(&argc, argv); - return RUN_ALL_TESTS(); -} \ No newline at end of file + ::testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +}