好吧,你不是 100% 清楚你对答案的期望,但我会尽量涵盖一般的想法。
首先,您可以称之为“调试”信号的是(以及何时期望它们):
SIGILL, SIGFPE— 如果程序试图运行非法指令,通常会出现错误CFLAGS和/或自己的程序集(或严重的随机损坏);
SIGABRT— 由abort()呼叫引起,例如在assert(). 它也可以来自库,因此您通常应该处理它;
SIGSEGV——无效的内存访问,你可能已经知道了;
SIGBUS— 在使用 I/Ommap()并尝试读/写不可访问的内存时可能发生;当mmap()基于 - 的 I/O 空间不足时,我也遇到过这种情况;
SIGPIPE— 在管道上进行 I/O 时,管道与另一端断开连接;
- POSIX 还指定
SIGSYS了无效的系统调用,您可能也想抓住它(尽管我从未设法看到一个)。
如果您使用相关操作,我会说您需要处理这些信号。它们都在 POSIX 中,但我不确定是否所有系统都实现了它们,所以#ifdef无论如何你可能都想为它们使用 s (SIG*保证是宏,因此适用于#ifdef)。
您在程序运行时可能遇到的其他信号是:
SIGALRM— 使用时alarm(),
SIGPOLL— 使用轮询时,
SIGCHLD— 当产生进程时……</li>
这些基本上是您在使用相关操作时正在处理的信号,尽管它们默认终止,但无论如何您都应该为它们提供其他处理程序。
最后,如果您希望处理user发送的信号,这是一个苛刻的情况——因为 user 实际上可以发送每个信号。因此,如果您想优雅地处理这一切,您需要捕获man signal默认为终止或中止操作的每个信号。
如果您只想捕获您可以预期的常见信号子集,这些将是:
SIGHUP当带有程序的终端(或其他相关的父级)死亡时,
SIGINT对于 ^c 键,
SIGQUIT对于 ^\ 键,
SIGTERM对于终止请求(kill默认由程序和其他类似工具发送),
SIGUSR1和SIGUSR2是用户定义的信号,通常用于执行程序特定的操作。它们是由用户发送的,并且——出于某种原因——默认杀死程序。
也有SIGKILL,但标准不允许捕捉它。
我希望我涵盖了最重要的信号。请注意,我是 Linux 用户,其他 *nixes 可能有一些您也可能想要捕捉的特定信号。
这通常完全取决于您想要实现的目标。虽然防止软件被随机信号打断是个好主意,但通常不值得阻止它被所有这些信号杀死,尤其是那些仅由用户直接发送的信号。
如果用户想要杀死应用程序,无论如何他都可以实现它,并且只需处理常见的应用程序就足够了 -SIGINT和SIGTERM. 我个人希望SIGQUIT(^\ key) 杀死应用程序而不让它完成甚至关键的任务(就像这样SIGKILL做)。
编辑. 作为最后一句话的理由,请考虑以下几点:我刚刚做了一些愚蠢的事情,比如删除了一些重要数据。或者只是注意到退出时清理程序有问题。我真的很想终止程序,确保我的信号不会被捕获,但会立即返回。即使它会导致数据损坏,有时我真的更喜欢有损坏的数据(希望我能够恢复我需要的东西)而不是没有数据。