// 看门狗 Monitor(双进程架构) // // 对应《VDI 云桌面软件开发方案》与会议纪要: // "必须部署独立的 Monitor(看门狗)程序监控主进程状态, // 主进程假死或崩溃时由 Monitor 执行 kill 操作并重启" // "小型 ARM 设备长时间运行必然出现卡顿或假死,无守护机制将导致用户体验严重受损" // // 判定主进程假死的方式: // 1. 进程不存在 -> 崩溃 // 2. 心跳文件超时 -> 假死(主进程定期写心跳,Monitor 检查更新时间) // 3. 连续启动失败 -> 熔断,放弃重启避免无限重启循环 // // 用法: // monitor -- <主进程命令行...> // 例:monitor -- /home/armbian/vdi-terminal/bin/kiosk-shell #ifndef KIOSK_SHELL_MONITOR_H #define KIOSK_SHELL_MONITOR_H #include #include namespace vdi { struct MonitorConfig { // 心跳文件路径;主进程每 heartbeatInterval 写一次 std::string heartbeatFile = "/tmp/vdi-kiosk.heartbeat"; // 心跳超时判定(毫秒) int heartbeatTimeoutMs = 15000; // 检查间隔(毫秒) int checkIntervalMs = 3000; // 心跳文件超过该时间认为进程从未启动 int startupGraceMs = 20000; // 连续失败多少次后熔断 int maxRestartAttempts = 5; // 两次重启之间的间隔(毫秒) int restartBackoffMs = 3000; // 是否在每条日志后写 stdout bool verbose = true; }; class Monitor { public: explicit Monitor(MonitorConfig config = MonitorConfig()); // 运行看门狗主循环,阻塞直到被信号中断 int run(const std::string& command); // 请求退出(供信号处理调用) void requestStop(); private: bool isProcessAlive(pid_t pid) const; // 主进程是否被认为假死 bool isHung() const; void log(const std::string& message) const; MonitorConfig config_; volatile bool stopRequested_ = false; int restartAttempts_ = 0; }; } // namespace vdi #endif // KIOSK_SHELL_MONITOR_H