如何在不杀死 Linux 中的应用程序的情况下发出信号?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/10824886/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to signal an application without killing it in Linux?
提问by Eric
I have a watchdog application. It watches my main app which might crash for one reason or another (I know it is bad, but this is not the point).
我有一个看门狗应用程序。它监视我的主应用程序,该应用程序可能因某种原因崩溃(我知道这很糟糕,但这不是重点)。
I programmed this watchdog to accept SIGUSR1 signals to stop monitoring my application presence. I signal it with
我将此看门狗编程为接受 SIGUSR1 信号以停止监视我的应用程序存在。我用它发出信号
kill -SIGUSR1 `pidof myapp`
This works really well. My problem comes when I try to signal an older version of the watchdog which does not have this functionality built in. In this case, the kill signal kills the watchdog (terminates the process), which leads to further complications (rebooting of the device).
这真的很好用。当我尝试向没有内置此功能的旧版看门狗发出信号时,我的问题就出现了。在这种情况下,kill 信号会杀死看门狗(终止进程),这会导致进一步的并发症(重新启动设备) .
Is there a way to signal my watchdog with SIGUSR1 so that it does not terminate if this particular signal is unhandled?
有没有办法用 SIGUSR1 向我的看门狗发出信号,这样它就不会在未处理此特定信号时终止?
采纳答案by Paulo Scardine
From the GNU docsabout signal handling:
来自关于信号处理的GNU 文档:
The SIGUSR1 and SIGUSR2 signals are set aside for you to use any way you want. They're useful for simple interprocess communication, if you write a signal handler for them in the program that receives the signal. There is an example showing the use of SIGUSR1 and SIGUSR2 in section Signaling Another Process. The default action is to terminate the process.
SIGUSR1 和 SIGUSR2 信号被留出供您以任何方式使用。如果您在接收信号的程序中为它们编写信号处理程序,它们对于简单的进程间通信很有用。在信令另一个进程部分中有一个示例显示了 SIGUSR1 和 SIGUSR2 的使用。 默认操作是终止进程。
The default action for SIGINFO is to do nothing, so it may be more suitable:
SIGINFO 的默认操作是什么都不做,所以它可能更合适:
SIGINFO: Information request. In 4.4 BSD and the GNU system, this signal is sent to all the processes in the foreground process group of the controlling terminal when the user types the STATUS character in canonical mode; see section Characters that Cause Signals. If the process is the leader of the process group, the default action is to print some status information about the system and what the process is doing. Otherwise the default is to do nothing.
SIGINFO:信息请求。在 4.4 BSD 和 GNU 系统中,当用户在规范模式下键入 STATUS 字符时,该信号会发送到控制终端前台进程组中的所有进程;参见引起信号的字符部分。如果进程是进程组的领导者,则默认操作是打印有关系统的一些状态信息以及进程正在做什么。否则默认是什么都不做。
SIGHUPis emitted when the controlling terminal is closed, but since most daemons are not attached to a terminal it is not uncommon to use it as "reload":
SIGHUP在控制终端关闭时发出,但由于大多数守护进程未连接到终端,因此将其用作“重新加载”并不少见:
Daemon programs sometimes use SIGHUP as a signal to restart themselves, the most common reason for this being to re-read a configuration file that has been changed.
守护程序有时使用 SIGHUP 作为重新启动自己的信号,最常见的原因是重新读取已更改的配置文件。
BTW, your watchdog could read a config file from time to time in order to know if it should relaunch the process.
顺便说一句,您的看门狗可能会不时读取配置文件,以了解它是否应该重新启动该过程。
My personal favorite for a watchdog is supervisor.
我个人最喜欢的看门狗是supervisor。
$ supervisorctl start someapp
someapp: started
$ supervisorctl status someapp
someapp RUNNING pid 16583, uptime 19:16:26
$ supervisorctl stop someapp
someapp: stopped
See if kill -l
returns the list of signals on your platform and try some of them, but SIGUSR1 seems like a bad choice.
查看是否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
[UPDATE]
[更新]
Carpetsmoker comments about differences in behavior between Linux and BSDs:
Carpetsmoker 评论 Linux 和 BSD 之间的行为差异:
SIGINFO seems to work different on GNU libc & BSD; on BSD, it works as you describe, but on Linux, it either doesn't exist, or is the same as SIGPWR... The GNU libc manual seems incorrect in this regard (your kill -l output also doesn't show SIGINFO)... I don't know why GNU doesn't support it, because I find it to be very useful... – Carpetsmoker
SIGINFO 在 GNU libc 和 BSD 上的工作方式似乎不同;在 BSD 上,它按您的描述工作,但在 Linux 上,它要么不存在,要么与 SIGPWR 相同...GNU libc 手册在这方面似乎不正确(您的 kill -l 输出也不显示 SIGINFO )...我不知道为什么 GNU 不支持它,因为我发现它非常有用... – Carpetsmoker
回答by Milan
The default action when receiving a SIGUSR1 is to terminate if the handler is not present. Meaning you can't do what you want with that signal anymore.
接收 SIGUSR1 时的默认操作是在处理程序不存在时终止。这意味着你不能再用那个信号做你想做的事了。
Short of updating the watchdog, there is nothing you can do (and I'm assuming that you are unable to differentiate watchdog versions from within the program prior to sending the signal).
除了更新看门狗之外,您无能为力(我假设您无法在发送信号之前从程序中区分看门狗版本)。