系统编程:信号(1)

2019-05-26

这篇博文只是记录我信号的一点笔记,并不详细也不权威,建议阅读《Linux/Unix系统编程手册》

下一篇:系统编程:信号(2)


信号是操作系统中一个重要的概念:是指某些事件发生时,对于进程的通知机制,也叫软件中断。

上面的解释似乎还不够具体,举两个例子:

  • 在shell中,运行一个耗时任务,如果我们想中途停止,那么我们可能习惯性的按下 Ctrl + C,任务就会停止。这里按下 Ctrl + C 后,内核就会给当前进程发送一个信号:SIGINT(终端中断信号),进程接受到就会停止运行。
  • 同样的,有时候我们可能会用kill这个命令来杀死一个进程,也就是:kill 进程号,进程就能停止了。原理是让内核给进程发送一个SIGTERM(终止进程信号),这样进程也会停止。 此处关于kill命令描述不严谨,后面会详细说道

信号的种类和默认行为

相信从上面的的概念解释中,已经明白了信号的含义了;那么自然会有两个疑问了:

  • 除了SIGINT SIGTERM这些信号,还有那些信号呢?也就是信号都有多少种呢?
  • SIGINT SIGTERM 这些的信号会让进程终止,那么其他信号对应的进程行为是什么呢?

Linux中标准信号有31个,分别是按照 1-31 进行编号,例如SIGINT对应的编号是2,SIGTERM对应的编号是15。

关于信号的描述放在man第7章中,我们可以通过 man 7 signal 来查看:

signal文档1 (这个文档我也只是稍微看过大概,很多也不是很清晰,就不扯太多了以免有错。)

这里我们先关注进程对于信号的处理,也就是上图中Signal dispositions这一节,从文档来看进程对信号的处理大概有几种:

  • Term; 终止进程
  • Ign ;忽略信号,也就是不做处理
  • Core ;终止进程,并产生dump文件,以便调试
  • Stop; 暂停进程,这里虽然是Stop,但区别于终止进程,这里是暂停进程的意思
  • Cont; 继续执行,如果这个进程当前是暂停的话

然后往下来,可以看到所有的信号,和他们对应的信号值,以及进程接受到信号时会采取的操作,以及产生信号的原因。 signal文档2

从上图就能看到 SIGINT 和 SIGTERM 信号对应的信号值分别是2和15,而他们对应的ACTION则都是Term也就是终止进程。

信号的发送:kill

结合前面说的能知道,通过按下Ctrl+C可以给当前shell运行的进程发送SIGINT信号,而通过kill 进程号能给进程发送SIGTERM信号。那么考虑:如果想给进程发送别的信号怎么办呢?

答案:还是 kill 命令。 kill命令其实是:给进程发送信号的命令,只不过默认的情况下,发送的是SIGTERM信号。可以通过man 1 kill来查看 kill 命令的详细文档。所以如果你愿意,可以通过 kill 命令来给进程发送别的信号。

通过 kill -l 能看到 kill 能发送的所有信号:

$ kill -l
HUP INT QUIT ILL TRAP ABRT BUS FPE KILL USR1 SEGV USR2 PIPE ALRM TERM STKFLT CHLD CONT STOP TSTP TTIN TTOU URG XCPU XFSZ VTALRM PROF WINCH POLL PWR SYS

再延伸一下,网上很多文档说,如果进程通过kill杀不掉,可以使用 kill -9 进程号 的方式来强杀,实际上就是给进程发送 9 这个信号,而通过上面的截图我们知道是SIGKILL信号,这个信号不能被阻塞,所以就一定能杀死进程。

kill 命令的底层实现,实际上也是内核提供了一个系统调用:int kill(pid_t pid, int sig)来供进程之间发送信号,关于这个kill()系统调用也可以看一下man 2 kill的文档,非常有帮助。

黔ICP备17000852号-4