You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C++调用reboot重启时SSH会话挂起,如何实现与CLI reboot一致的断开效果

问题原因

你直接调用reboot(RB_AUTOBOOT)属于内核级的直接重启操作,会跳过用户态的服务优雅关闭流程:sshd服务没有机会执行正常的连接销毁逻辑,无法主动向SSH客户端发送连接断开的报文,导致客户端一直等待服务端响应,就出现了连接挂起的现象。
而系统自带的reboot、shutdown -r now命令不会直接触发内核重启,会先通知init系统(systemd、sysvinit等)执行完整的关机流程:按顺序停止所有运行中的服务,sshd会在这个阶段主动关闭所有活跃连接,给客户端返回连接关闭提示,最后才会调用内核的重启接口。

解决方案

推荐你优先选择更兼容的实现方式,不要直接调用内核reboot系统调用:

方案1:直接调用系统原生重启命令

在C++代码中通过system或者exec族函数调用系统自带的重启命令,自动走完整的服务关闭流程:

// 需要程序以root权限运行
system("shutdown -r now");

如果需要规避shell注入风险,可以使用execv直接执行命令文件:

#include <unistd.h>
#include <sys/wait.h>

// 子进程执行重启命令
if (fork() == 0) {
    char* const args[] = {"/usr/sbin/shutdown", "-r", "now", NULL};
    execv(args[0], args);
    exit(1);
}
// 父进程等待子进程执行完成即可
wait(NULL);

方案2:通知init系统触发重启(适配systemd场景)

如果不想调用外部命令,对于使用systemd的发行版,可以给1号init进程发送指定信号触发重启流程,同样会走完整的服务关闭逻辑:

#include <sys/types.h>
#include <signal.h>

// SIGRTMIN+13 是systemd约定的触发重启的信号
kill(1, SIGRTMIN + 13);

特殊场景兼容方案

如果你的业务场景必须直接调用reboot系统调用,可以在调用前先主动关闭sshd服务,触发SSH连接正常断开:

system("systemctl stop sshd"); // 先关闭sshd服务
sync();
reboot(RB_AUTOBOOT);

该方案兼容性较差,不同发行版的sshd服务名、管理方式可能存在差异,仅作为兜底选项使用。

注意事项

以上所有方案都需要你的C++程序以root权限运行,和执行sudo reboot的权限要求一致。

内容的提问来源于stack exchange,提问作者svanschu

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.05 08:09:03