【问题标题】:How to signal an application without killing it in Linux?如何在 Linux 中向应用程序发出信号而不杀死它?
【发布时间】:2012-05-30 22:01:50
【问题描述】:

我有一个看门狗应用程序。它监视我的主应用程序,该应用程序可能由于某种原因崩溃(我知道这很糟糕,但这不是重点)。

我将此看门狗编程为接受 SIGUSR1 信号以停止监视我的应用程序的存在。我用

发出信号
kill -SIGUSR1 `pidof myapp`

这真的很好用。当我尝试向没有内置此功能的旧版本看门狗发出信号时,我的问题就出现了。在这种情况下,kill 信号会杀死看门狗(终止进程),这会导致进一步的并发症(重新启动设备) .

有没有办法用 SIGUSR1 向我的看门狗发出信号,以便在这个特定信号未处理时它不会终止?

【问题讨论】:

  • "...我知道这很糟糕,但这不是重点" - 你把牛奶放在我的鼻子上 :) 为此 +1。

标签: linux signals


【解决方案1】:

来自GNU docs关于信号处理:

SIGUSR1 和 SIGUSR2 信号被预留出来供您以任何方式使用。如果您在接收信号的程序中为它们编写信号处理程序,它们对于简单的进程间通信很有用。 在 Signaling Another Process 部分中有一个示例显示了 SIGUSR1 和 SIGUSR2 的使用。 默认操作是终止进程

SIGINFO 的默认动作是什么都不做,所以可能更合适:

SIGINFO:信息请求。在 4.4 BSD 和 GNU 系统中,当用户在规范模式下键入 STATUS 字符时,该信号被发送到控制终端的前台进程组中的所有进程;请参阅导致信号的字符部分。 如果进程是进程组的leader,默认的动作是打印一些关于系统的状态信息以及进程在做什么。 否则默认不做任何事情

SIGHUP 在控制终端关闭时发出,但由于大多数守护程序未连接到终端,因此将其用作“重新加载”并不少见:

守护程序有时会使用 SIGHUP 作为重启自身的信号,最常见的原因是重新读取已更改的配置文件。

顺便说一句,您的看门狗可能会不时读取配置文件,以了解它是否应该重新启动该进程。

我个人最喜欢看门狗是supervisor

$ supervisorctl start someapp
someapp: started

$ supervisorctl status someapp
someapp                RUNNING    pid 16583, uptime 19:16:26

$ supervisorctl stop someapp
someapp: stopped

查看kill -l 是否返回您平台上的信号列表并尝试其中一些,但 SIGUSR1 似乎是一个糟糕的选择。

$ kill -l
 1) SIGHUP       2) SIGINT       3) SIGQUIT      4) SIGILL       5) SIGTRAP
 6) SIGABRT      7) SIGBUS       8) SIGFPE       9) SIGKILL     10) SIGUSR1
11) SIGSEGV     12) SIGUSR2     13) SIGPIPE     14) SIGALRM     15) SIGTERM
16) SIGSTKFLT   17) SIGCHLD     18) SIGCONT     19) SIGSTOP     20) SIGTSTP
21) SIGTTIN     22) SIGTTOU     23) SIGURG      24) SIGXCPU     25) SIGXFSZ
26) SIGVTALRM   27) SIGPROF     28) SIGWINCH    29) SIGIO       30) SIGPWR
31) SIGSYS      34) SIGRTMIN    35) SIGRTMIN+1  36) SIGRTMIN+2  37) SIGRTMIN+3
38) SIGRTMIN+4  39) SIGRTMIN+5  40) SIGRTMIN+6  41) SIGRTMIN+7  42) SIGRTMIN+8
43) SIGRTMIN+9  44) SIGRTMIN+10 45) SIGRTMIN+11 46) SIGRTMIN+12 47) SIGRTMIN+13
48) SIGRTMIN+14 49) SIGRTMIN+15 50) SIGRTMAX-14 51) SIGRTMAX-13 52) SIGRTMAX-12
53) SIGRTMAX-11 54) SIGRTMAX-10 55) SIGRTMAX-9  56) SIGRTMAX-8  57) SIGRTMAX-7
58) SIGRTMAX-6  59) SIGRTMAX-5  60) SIGRTMAX-4  61) SIGRTMAX-3  62) SIGRTMAX-2
63) SIGRTMAX-1  64) SIGRTMAX

[更新]

Carpetsmoker 了解 Linux 和 BSD 之间的行为差​​异:

SIGINFO 在 GNU libc 和 BSD 上的工作方式似乎有所不同;在 BSD 上,它按照您的描述工作,但在 Linux 上,它要么不存在,要么与 SIGPWR 相同......在这方面 GNU libc 手册似乎不正确(您的 kill -l 输出也不显示 SIGINFO )...我不知道为什么 GNU 不支持它,因为我发现它非常有用... – Carpetsmoker

【讨论】:

  • SIGINFO 在 GNU libc 和 BSD 上的工作方式似乎有所不同;在 BSD 上,它按照您的描述工作,但在 Linux 上,它要么不存在,要么与 SIGPWR 相同... GNU libc 手册在这方面似乎不正确(您的 kill -l 输出也不show SIGINFO)...我不知道为什么 GNU 不支持它,因为我发现它非常很有用...
【解决方案2】:

接收到 SIGUSR1 时的默认操作是在处理程序不存在时终止。这意味着你不能再用那个信号做你想做的事了。

没有更新看门狗,您无能为力(我假设您无法在发送信号之前从程序中区分看门狗版本)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-08-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-26
    • 2014-05-22
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多