微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

我最早可以注册信号处理程序是什么时候?

如何解决我最早可以注册信号处理程序是什么时候?

我有一个 C 程序。我希望它在收到 SIGTERM 时总是干净地退出退出代码为 0。我可以注册信号处理程序的最早位置是什么?我将它添加main() 的顶部,但我担心它可能会在信号注册之前获得一个 sigterm。

是否可以更早地注册信号处理程序?

解决方法

是的,你可以。使用平台特定的初始值设定项,例如 gcc 的 __attribute((constructor))。但这并不是一个可靠的解决方案。

如果您希望“在收到 SIGTERM 时始终以退出代码 0 干净地退出”,则指示进程生成代码以 SIGTERM blocked 开头。 >

然后您的 main 可以注册一个信号处理程序并解除对 SIGTERM 的阻塞(使用 sigprocmaskpthread_sigmask,此时如果收到信号处理程序将立即运行在进程创建到解除信号阻塞调用之间的任何时间点。

本质上,它会将信号的传递推迟到您准备好处理它的程度。

(请注意,如果您在忽略而不是阻止信号的情况下启动进程,则接收到的信号的任何实例直到忽略该信号都将丢失,就好像它们从未发生过一样。这似乎与您所说的背道而驰要求。)

,

如果可以切换到 C++:在程序开始和 main 之间初始化全局变量。因此,理论上您可以使用如下代码在调用 main 之前运行。

int f() {
  signal(...);
  return 0;
}
int x = f();

但是您无法保证全局对象的初始化顺序,因此 x 可能不会首先初始化,而是最后初始化。

但是回到您最初的要求:启动程序和 main 之间的时间如此之短,您为什么要在这么短的时间内为有人发送 SIGTERM 做好准备?这不是不太可能发生吗?

如果可能,您可以将父级更改为忽略 SIGTERM,然后是 forkexecvesignal man page

通过 fork(2) 创建的子级继承了其父级的副本 信号处置。在 execve(2) 期间, 处理的信号被重置为默认值;的处置 忽略的信号保持不变。

因此您可以忽略 SIGTERM 开始您的进程,直到它为 SIGTERM 设置处理程序。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。