linux下程序崩溃后自动拉起应使用systemd管理,通过restart=always或on-failure配合restartsec实现秒级重启,避免在c++中自行捕获sigsegv等信号;windows则需注册为服务并配置scm的failureactions。

程序崩溃后怎么让进程自己拉起来?
Linux 下最直接的办法是用 systemd 管理进程,而不是在代码里“捕获 segfault”——C++ 没法可靠拦截 SIGSEGV 做自愈,强行 set_signal_handler + longjmp 容易引发资源泄漏或二次崩溃。systemd 的 Restart=always 和 RestartSec=1 能真正实现崩溃后秒级重启,且自动清理孤儿子进程、重置文件描述符。Windows 则依赖服务控制管理器(SCM),把程序注册为 Windows Service 并设置 FailureAction,比自己 fork 子进程看管父进程更稳定。
常见错误:写个 while 循环不断 fork 子进程监控自己,结果崩溃时子进程也卡死或产生僵尸进程;或者用 atexit() 注册清理函数,但崩溃时根本不会触发。
- Linux:确保
Restart=on-failure或always,配合StartLimitIntervalSec=0关闭启动频率限制(调试期) - Windows:服务安装时用
sc create设置start= auto和error= ignore,失败动作需通过ChangeServiceConfig2设置 - 不要依赖
std::set_terminate或signal(SIGSEGV, ...)做“恢复”,它们只能记录日志,不能阻止崩溃或恢复状态
网络请求失败时怎么安全地重试?
重试不是简单 for 循环加 sleep,关键在于判断是否可重试、避免幂等性破坏、控制退避节奏。std::this_thread::sleep_for 配合指数退避(exponential backoff)是主流做法,但必须结合 HTTP 状态码或 errno 类型来决策:比如 ECONNREFUSED 可重试,EINVAL 或 400 Bad Request 就不该重试。
示例逻辑:三次重试,间隔分别为 100ms、300ms、900ms,每次失败后检查 errno 是否属于临时错误(EAGAIN、EWOULDBLOCK、ECONNRESET)。
- 用
std::chrono::milliseconds控制休眠,别用sleep(1)这种粗粒度方式 - 重试前清空 socket 缓冲区或重建连接对象,避免复用已半关闭的 fd
- 对 POST/PUT 请求,除非服务端明确支持幂等(如带
Idempotency-Key),否则重试可能重复提交
文件读写失败后要不要重试?重试几次?
文件操作失败是否重试,取决于错误类型和场景。磁盘满(ENOSPC)、权限不足(EACCES)这类错误重试毫无意义;而 ETXTBSY(文件正被执行)、EBUSY(设备忙)则可能短暂存在,值得等一等再试。
组合式C++代码评审方案,融合静态分析、AI推理、多轮迭代评审和C++专项检查,适用于PR审查、增量代码审查、全项目评审和代码质量评分,触发词包括review cpp、cpp代码评审、C++review、代码审查。
典型做法:对 open/write/fstat 等调用,捕获 errno 后白名单过滤可重试错误,最多 3 次,每次间隔 10–50ms(避免毛刺干扰)。注意 fopen 不暴露 errno,得用 open() + write() 系统调用链才能精准判断。
-
open()失败时检查errno == EINTR—— 这不是错误,应直接重试,不用计次 - 写入日志文件时遇到
ENOSPC,应立即切换到备用路径或触发告警,而不是循环等待磁盘释放 - 使用
O_NONBLOCK打开设备文件时,read()返回 -1 且errno == EAGAIN是正常现象,必须重试
如何避免重试逻辑变成雪崩?
无节制重试会让下游压力倍增,尤其在集群中容易引发级联故障。必须加限流和熔断:单个请求最大重试次数硬限制(如 3 次),全局重试速率限制(如每秒最多 10 次重试请求),以及连续失败达阈值后主动熔断(如 5 分钟内失败超 20 次,停用该服务端点 60 秒)。
一个轻量方案:用 std::atomic_int 记录失败计数,配合 std::chrono::steady_clock 滚动窗口统计,不依赖外部库。熔断状态存在内存里即可,不需要持久化——进程重启后自然恢复。
- 重试间隔必须随机化(jitter),比如在
base * 2^n基础上 ±10%,防止大量实例在同一时刻重试 - 记录每次重试的
errno和耗时,用syslog或spdlog输出,方便定位是网络抖动还是服务端真挂了 - 不要在信号处理函数里做重试逻辑——信号上下文不可重入,
malloc、printf都不安全
自愈和重试的边界很窄:系统级崩溃靠外置守护进程兜底,业务级失败才进代码逻辑;而任何重试都必须有明确退出条件,否则只是把失败延迟成超时。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!










