Linux 应用程序开发和信号处理

Man*_*d3r 5 c signals

目前,我的用户抱怨我的应用程序终止时遇到问题。在某些(看似随意的)条件和桌面环境下,应用程序不会终止,并且设置不会在重启时保存。我在相关的 irc 频道中询问,大部分时间我都被告知要正确处理信号。我知道终端中 Ctrl-C 的 SIGINT 和“正常”终止的 SIGTERM。但有人告诉我 SIGHUP 也很重要。所以我的问题是:

我必须处理哪些信号才能构建性能良好的应用程序?

PSk*_*cik 2

https://en.wikipedia.org/wiki/Unix_signal

有一个标准信号及其默认操作的列表。任何有足够特权的进程总是可以向您发送任何信号,但进程(或您,通过进程)不应该这样做。

您应该只kill使用并期望您的进程使用killTERM可由您的环境(shell、终端驱动程序)生成的一堆信号,除非您知道目标处理您想要发送的特殊信号。

您可以按操作对基本信号进行排序。

核心转储信号

ABRT TRAP SYS BUS FPE ILL SEGV   XFSZ XCPU QUIT
Run Code Online (Sandbox Code Playgroud)

要么是由您(TRAP、ABRT、SYS)使用某些专用函数生成的,要么是由您进入硬错误状态(BUS、FPE、ILL、SEGV)生成的。 QUIT由用户在想要核心转储的终端上生成 ( C+\)。

您可能希望将它们保留为默认配置。

在终止信号之外:

HUP INT PIPE TERM ALRM POLL PROF USR1 USR2
Run Code Online (Sandbox Code Playgroud)

你应该期待

HUP INT PIPE TERM
Run Code Online (Sandbox Code Playgroud)

根据您的环境在不同情况下的情况:

HUP -- when the terminal hungs up or you become a stopped orphaned process
INT -- when the user at the terminal interrupts you with C-c
PIPE -- when a PIPE or socket you write into closes, e.g. by
        exiting before you finished writing to it 
       (`yourprogram | (exit)` will give you a `PIPE` 
        if yourprogram attempts to write to its STDOUT) 
TERM -- when a process ends you a normal termination request
Run Code Online (Sandbox Code Playgroud)

仅当您自己设置时,您才应该收到其余的终止信号。

杀戮阻止你无能为力。

您可能希望拦截终端生成的停止信号

TTIN -- you read from the terminal and you're a backgrounded process
TTOU -- you write the terminal when you're a backgrounded process
        and the terminal is set to put you to sleep when you do
TSTP -- you're being put to sleep with `C-Z`
Run Code Online (Sandbox Code Playgroud)

但最坏的情况是,这些只会停止您的进程,而不会破坏您的状态。

除非您知道需要处理CHLDCONT、 或URG,否则您不需要。

长话短说:

基本上,我认为如果您通常想要进行一些退出前清理,则应该处理(或忽略)HUP、INT、PIPE 和 TERM。其余的可以不用管,除非你的程序使用这些信号,或者除非你在所有情况下都绝对需要一些清理。

在后一种情况下,您可以空白地阻止所有未处理的信号,但要注意信号阻止掩码会在 fork 和 execve 调用之间继承,并忽略或阻止像 ILL 这样的信号(如果它们是在进程运行时产生的并且没有发送给您)通过kill 或sigqueue 会给你未定义的行为。

如果您想了解更多信息,请浏览联机帮助页和标准。信号在 Unix 上是一个相当大的话题,处理它们可能会变得非常棘手。