在Linux中杀死信号

时间:2020-03-05 15:28:40  来源:igfitidea点击:

Linux中的信号是一个非常重要的概念。
这是因为在我们通过Linux命令行执行的一些常见活动中使用了信号。
例如,每当我们按“ Ctrl + c”以从命令行终止执行命令时,便会使用信号。

每当我们使用“ kill -9 [pid]”杀死一个进程时,都会使用信号。
因此,至少了解信号的基础非常有用,而这正是我们将在本教程中讨论的内容。

什么是信号?

信号不过是将消息从一个进程传递到另一个进程的一种方式。
这些消息通常称为通知,接收过程可以自由处理,忽略或者留给操作系统以采取默认操作(有关这些选项的更多信息,请稍后)。
由发送方进程发送到接收进程的通知可以是各种类型。
例如,一个通知可以是终止接收过程,或者让它知道它已经访问了无效的内存区域,或者可以是有关资源可用性(之前很忙)的通知等。
因此,我们可以看到信号不过是IPC(进程间通信)的另一种方式。

为什么信号很重要?

信号很重要,实际上非常重要,因为信号会驱动一些最流行的编程和系统管理活动。
例如,让我们以调试器为例。
大多数程序员在执行程序时都使用调试器来调试其程序代码。
如果我们曾经使用过调试器,那么我们会知道断点用于在指定的代码行中停止程序的执行。

我们是否曾经想到过什么使程序意识到断点已被击中并且需要暂停执行?
是的,在这种情况下,它是一个发送到程序的信号(SIGSTOP)。
并且,当用户完成调试后,信号(SIGCONT)将发送到程序-之后程序将继续执行。

因此,这是一个例子。
但是还有许多其他活动完全取决于信号。

程序如何处理信号?

程序可以通过以下三种方式处理信号:

  • 程序可以提供自己的信号处理程序来处理特定信号-在程序必须响应接收到的信号执行某些任务(例如,内存清理活动)的情况下,这尤其重要。信号处理程序不过是程序代码中定义的函数,当程序接收到信号时,该函数会自动执行(实际上是由OS内核触发)。
  • 程序在收到信号后可能什么也不做-每个信号都有与之关联的默认操作。在程序根本不关心信号的情况下,与该特定信号相对应的默认操作由OS内核执行。
  • 程序可以选择忽略信号-在这种情况下,信号(或者信号集)被阻止,因此不会传递给程序。程序可能会选择忽略程序员认为与之无关的信号。

不同类型的信号

要获取Linux系统上支持的信号列表,只需发出以下命令:

kill -l

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

因此,我们可以看到输出包含我的系统支持的所有信号。
要了解一些流行的信号,请阅读C++ Signals教程。

如果我们是系统管理员或者高级命令行用户,那么我们肯定会使用以下命令来杀死进程:

kill -9 <pid>

其中pid是我们要终止的进程的标识符。

我们是否曾经想过-9到底意味着什么?
好吧,它表示信号的数值为9.
是的,信号(如我们在上面的'kill -l'的输出中可以看到的)具有与之关联的数值。
要知道哪个信号的数值为9,请使用以下命令:

$kill -l 9
KILL

因此,我们可以看到数值9对应于SIGKILL。
同样,如果需要将信号名称转换为其数值,则可以使用相同的命令。

例如 :

$kill -l KILL
9

因此,我们可以看到以这种方式可以提取与信号名称相对应的数字值。

SIGSTOP和SIGKILL信号

信号SIGSTOP和SIGKILL值得特别提及,因为这些信号不能由程序处理。

SIGSTOP该信号由进程发送,以暂停程序以便可以对其进行调试。
现在,假设如果程序具有处理该信号的能力,并且程序无意中选择了忽略该信号,则该程序将永远无法调试。

SIGKILL该信号由进程发送,以便立即终止接收进程。
这意味着终止是异常的而不是正常的。
在进程挂起或者要立即终止的情况下使用此信号-例如,有时在系统关闭时OS内核会使用此信号。

信号特征

以下是Linux信号的一些重要特征:

  • 如果一个进程具有多个线程,则信号仅中断一个线程,而不中断整个进程-这适用于2.6或者更高版本的Linux内核。
  • 信号处理程序也可能会因为收到另一个信号而中断
  • 除了标准的信号集。也可以有用户定义的信号。
  • 就代码而言,可以通过使用诸如signal()和sigaction()之类的函数来完成信号处理。