跨平台进程保活核心是“判断存活+按需拉起”,须按平台特性分别实现:windows用createtoolhelp32snapshot查进程名,linux/macos用pgrep -f,禁用硬编码路径与高频轮询,采用可配置休眠(如首次0ms、后续10秒),并加入重启防抖与失败计数机制。

保活监控器的核心逻辑必须绕开平台特有API
直接调用 CreateProcess(Windows)或 fork+exec(Linux/macOS)写死路径会导致编译失败或运行时崩溃。跨平台进程保活的关键不是“启动”,而是“判断是否存活 + 按需拉起”。所有平台都支持通过进程名或PID查状态,但实现方式不同:Windows 用 EnumProcesses + GetModuleBaseName,Linux/macOS 用 /proc 或 ps 命令解析。别试图封装成统一接口——先保证每个平台能跑通,再用预处理器隔离。
用 std::this_thread::sleep_for 避免轮询烧CPU
高频轮询(比如每100ms查一次)在后台服务里是反模式。实际部署中,5–30秒检查间隔更合理。C++11 起 std::this_thread::sleep_for 是唯一可移植的休眠方案,usleep、Sleep、nanosleep 全部被排除。注意:休眠时间不能写死为常量,要允许配置;且首次启动后应立即检查一次,避免“启动即挂”却等下一个周期才发现。
- 推荐初始检查延迟设为
0ms,后续固定为std::chrono::seconds(10) - 不要用
std::this_thread::yield()替代休眠——它不保证让出时间片,反而可能持续占满一个核 - 如果程序需要响应信号(如 SIGTERM)退出,休眠期间无法捕获,得用带超时的条件变量或
select(POSIX)/等待对象(Windows),但这就脱离“简单”范畴了
进程存在性判断要避开权限和竞态问题
Linux 下读 /proc/[pid]/comm 最快,但普通用户无权访问其他用户的 /proc 子目录;macOS 没有 /proc,得走 pgrep -f 或 ps -eo pid,comm 解析;Windows 的 OpenProcess 对已退出但句柄未关闭的 PID 会返回有效句柄,必须配合 GetExitCodeProcess 判断真实状态。最稳的折中方案:按名称查,不依赖 PID。
- Linux/macOS:执行
pgrep -f "my_app_name",检查 stdout 是否非空;避免用ps aux | grep,grep 自身会出现在结果里造成误判 - Windows:用
CreateToolhelp32Snapshot遍历进程,比 WMI 快且无需 COM 初始化;匹配szExeFile字段(不含路径的镜像名) - 永远不要假设“查到PID就等于进程活着”——它可能正处在僵尸/僵死状态,下一步必须验证可通信性(如尝试连本地 socket 或发信号)
重启策略必须加防抖和失败计数
进程闪退后立刻拉起,若程序本身有初始化缺陷,会触发“启动→崩溃→再启动”死循环,把系统日志撑爆。简单保活器至少要带两个控制维度:单次失败后延迟重启(比如指数退避:1s → 2s → 4s),以及连续失败阈值(如5次后停机并写日志)。
- 记录上次启动时间戳,每次失败后更新;若10秒内失败≥3次,跳过重启,只记录
"Too many crashes, aborting respawn" - 重启命令必须用绝对路径,且显式指定工作目录(
chdir或启动参数),否则子进程可能因找不到资源文件而再次崩溃 - Windows 下用
CreateProcess启动时,bInheritHandles设为false,避免把监控器的句柄泄露给被保活进程
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!











