为什么许多Unix程序使用像USR1这样的信号?

时间:2011-03-18 10:46:45

标签: linux unix nginx signals

许多Unix程序接受USR1USR2等信号。例如,要动态升级Nginx的可执行文件,请发送kill -USR2

我理解USR1是一个“用户定义”信号,这意味着创建该程序的任何人都可以使用它来表示“关闭”或“转储日志”或“打印foo一千次”等等。但我不明白为什么他们必须使用这个任意名称。为什么不kill -UPGRADEkill -GRACEFUL_SHUTDOWN? Unix只允许特定信号吗?

当我们接触它时,Nginx也使用以下信号(参见documentation):

  • TERM,INT :快速关机
  • 退出:正常关机
  • HUP
    • 配置重新加载
    • 使用新配置启动新的工作进程
    • 正常关闭旧工作进程
  • USR1 :重新打开日志文件
  • USR2 :即时升级可执行文件
  • WINCH :正常关闭工作进程

HUP?绞车?这些名字的原因是什么?我在哪里可以了解更多相关信息?

6 个答案:

答案 0 :(得分:74)

OS上可用的信号由OS定义(通常在POSIX之后) - 它们不是“字符串”,而是具有标准名称的整数常量。 USR1USR2是两个没有附加特定含义的信号 - 用于开发人员想要的任意用途。

在您的Linux机器上,阅读man 7 signal以获取信号处理和信号的概述。

如果您准备处理响应事件发出这些信号的操作系统,您可以重新定义其他信号的含义。你可以,例如make HUP表示“重新加载配置” - 只要您确定该进程永远不会发生挂起(终端丢失),或者您已准备好处理操作系统而非用户发送的情况HUP信号。

答案 1 :(得分:18)

HUP是“挂断”的缩写。如果其控制终端到达文件结尾,则将该信号发送到进程。在过去,控制终端通常连接到串行端口,可能通过电话线上的调制解调器链路。如果电话连接挂断,本地调制解调器将降低载波检测线,这将导致内核报告文件结束并发送SIGHUP信号。

WINCH是“窗口更改”的缩写。如果其控制终端改变大小,则将其发送到进程。出于显而易见的原因,可以改变大小的终端通常是伪终端,最终由在窗口环境中运行的终端仿真器表示(如xterm)。

答案 2 :(得分:9)

尝试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

答案 3 :(得分:8)

因为信号的名称是标准化的(通过POSIX)。如果需要,您可以编写自己的kill类型可执行文件以获取-UPGRADE信号,但是UNIX附带的标准USR1将无法识别它。

或者,您可以创建别名,函数或shell脚本来为您进行翻译,例如使用kill别名:

bash

alias upgrade='kill -USR1' 头文件将信号名称映射到它们的实际值,这些值与实现有关。

signal.h而言,我认为这有点令人厌恶。这是当窗口大小发生变化时(特别是当控制终端的窗口发生变化时)传递给应用程序的信号。

使用它来优雅地关闭工作线程不是一个好主意,除非你能保证进程永远不会在终端中运行。我知道如果我正在运行一个应用程序,我会非常恼火,它决定取消所有飞行中的工作,因为我最大化了窗口: - )

答案 4 :(得分:4)

在POSIX兼容平台上,SIGUSR1SIGUSR2是发送到进程的信号,用于指示用户定义的条件。它们的符号常量在头文件signal.h中定义。使用符号信号名称是因为信号编号可能因平台而异。

SIG是信号名称的通用前缀。 USR是用户定义的缩写。

答案 5 :(得分:4)

信号名称的起源时间早于Posix。

我想谈谈SIG ** IOT **。在使用DEC PDP主机的时代,使用的处理器有一个特殊的IOT指令(I / O陷阱),它通常用于轻轻地使系统崩溃 - 通常强制它重启(在实时服务器中)。整个内核以及设备驱动程序和特权进程(使用汇编程序编写)使用此方法。即便在今天,仍然有处理器仍然有这个IOT指令。

因此,当内核在非特权域中遇到IOT指令的执行时,它会向受影响的进程发出一个SIGIOT。