守护进程不该响应sigint和sigquit,因其已脱离控制终端,内核不递送sigint;sigquit则会触发无意义且存安全隐患的core dump,应显式忽略,专注处理sigterm、sighup等运维信号。

守护进程通常不响应 SIGINT 和 SIGQUIT,因为它们设计为在后台长期运行,不应被终端中断信号干扰。强行让守护进程处理这两个信号,反而可能破坏其稳定性或导致非预期退出。
为什么守护进程不该响应 SIGINT
SIGINT(编号 2)本质是面向前台交互进程的中断信号,由 Ctrl+C 触发,依赖控制终端(controlling terminal)。而标准守护进程在启动时已脱离终端:调用 setsid() 创建新会话、重定向 stdin/stdout/stderr 到 /dev/null、更改工作目录。此时它不再拥有控制终端,内核也不会向其递送 SIGINT —— 即使你注册了 handler,实际也收不到该信号。
若强行保留 SIGINT 处理逻辑,可能带来误导:开发者误以为 Ctrl+C 能终止服务,但实际无效;或者在调试阶段意外启用终端关联,导致信号行为不可靠。
SIGQUIT 的特殊风险
SIGQUIT(编号 3)默认动作是终止 + 生成 core dump。对守护进程而言,core dump 不仅占用磁盘空间,还可能泄露敏感内存数据(如密钥、凭证、未加密缓存),且多数守护进程运行在无调试环境的生产服务器上,core 文件既难分析又无价值。
更关键的是,SIGQUIT 无法被忽略(实际可忽略,但不推荐),但它的默认行为对守护进程毫无意义。应显式设为 SIG_IGN,避免意外触发 dump 或被误用为“强制退出”手段。
真正该关注的信号
守护进程应专注响应以下信号:
- SIGTERM(15):标准优雅关闭信号,用于 systemd stop、supervisorctl stop、普通 kill 命令。必须实现清理逻辑(关闭监听套接字、等待子进程、释放锁等)。
- SIGHUP(1):常用于重载配置(如 nginx -s reload),需重新读取配置文件、平滑重启 worker,不中断服务。
- SIGUSR1/SIGUSR2(10/12):用户自定义信号,可用于触发日志轮转、状态dump、调试信息输出等运维操作。
代码层面的安全设置
初始化阶段应明确屏蔽或忽略无关信号:
- 调用
signal(SIGINT, SIG_IGN)和signal(SIGQUIT, SIG_IGN),确保不会因继承父进程的 handler 而意外响应; - 使用
sigprocmask()在主线程中阻塞 SIGINT/SIGQUIT,防止多线程环境下信号被错误投递; - 对 SIGTERM 和 SIGHUP 使用
sigaction()注册 handler,设置SA_RESTART标志以避免系统调用被中断后返回 EINTR。











