为什么Unix程序不能用有意义的程序定义名称(而不是USR1等)发出信号?


78

许多Unix程序接受诸如USR1和的信号USR2。例如,要即时升级Nginx的可执行文件,请发送kill -USR2

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

在我们讨论它的同时,Nginx还使用以下信号(请参阅文档):

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

UP?绞盘?这些名字的原因是什么?在哪里可以了解更多信息?


1
一无所有-nginx使用QUIT进行正常关机很有趣。传统上,它类似于TERM + dump-a-core。TERM可以正常关机。这完全取决于您如何处理信号,但是当开发人员偏离常规时,这很奇怪。
synthesizerpatel

1
TIL:man signal讨论信号并列出其中的31个。
内森·朗

Answers:


80

操作系统上可用的信号由操作系统定义(通常在POSIX之后)-它们不是“字符串”,而是带有标准名称的整数常量。USR1并且USR2是两个没有特定含义的信号-用于开发人员想要的任意用途。

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

如果您准备好处理响应事件而发出这些信号的操作系统,则可以重新定义其他信号的含义。例如HUP,只要确定该过程永远不会挂断(终端丢失),或者您准备处理操作系统而不是用户发送HUP信号的情况,就可以使“重新加载配置”成为可能。 。


22

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

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


10

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

9

因为信号名称是标准化的(通过POSIX)。您可以编写自己的kill-type可执行文件,以-UPGRADE在需要时接收并传递USR1信号,但是killUNIX随附的标准无法识别它。

另外,您可以创建一个别名,函数或shell脚本来为您进行翻译,例如使用bash别名:

alias upgrade='kill -USR1'

signal.h头文件中的信号名称映射到它们的实际值,这是实现相关。

在方面WINCH,我认为这有点可憎。这是在窗口大小更改时(特别是在其控制终端的窗口更改时)传递给应用程序的信号。

除非可以保证进程永远不会在终端中运行,否则使用它来正常关闭工作线程不是一个好主意。我知道如果我正在运行一个应用程序,我会感到非常沮丧,它决定取消所有飞行中的工作,只是因为我最大化了窗口:-)


1
啊-当然,kill它本身是一个程序,不会知道-UPGRADE。我没想到。:)
内森·朗

5

在符合POSIX的平台上,SIGUSR1并且SIGUSR2是发送到进程以指示用户定义条件的信号。它们的符号常量在头文件中定义signal.h。之所以使用符号信号名称,是因为信号编号可能会因平台而异。

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


3
一个示例是ext {2,3,4}的变体,fsck其变体在USR1上将开始打印进度信息并在USR2上停止。当您遇到一些文件系统问题时,非常方便,从应急CD引导,启动fsck解决问题,然后过了一会儿无聊的等待,意识到“该死,我应该指定一些选项来启用进度信息”。
2014年

5

信号名称起源于Posix。

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

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

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.