一. 信号
我们在shell下运行起来一个程序,可以在这个进程正在运行的时候键盘输入一个Ctrl+C,就会看到这个进程被终止掉了,其实当我们键入Ctrl+C的时候是向进程发送了一个SIGINT信号,这时候产生了硬件中断则系统会从执行代码的用户态切入到内核态去处理这个信号,而一般这个信号的默认处理动作是终止进程,因此正在运行的进程就会被终止了。像SIGINT就是系统中定义的一个信号,除此之外还有其他信号,可以通过 kill -l 命令来查看:
如上图中有从1到64的各种信号,但是32和33号信号并没有,因此系统中一共有62个信号,其中1至31号是系统中的普通信号,而34到64是实时信号,这里暂不讨论。
-------------------------------------------------------------------------------------------
二. 信号的产生
那么,像上面的那些信号都是如何产生的呢?
首先,是由终端输入产生的,就像刚才举的栗子,从键盘输入一条命令其实就是在向一个进程发送特定的信号,但是像Ctrl+C这条命令只能发给前台进程,对后台进程是不起作用的,一个shell可以同时运行一个前台进程和多个后台进程;
其次,可以调用系统函数向进程发送信号,比如kill命令其实是终止一个进程,但kill命令是调用kill函数来实现的,kill函数可以给一个指定的进程发送特定的信号,其命令使用如下:
在上面的命令中,signal是为指定要发的信号,可以是信号的名字也可以是上面图片中每个信号前面的代码号;而pid就表示要发送信号的进程的pid号;
下面就可以写一个死循环的程序并且放在后台运行,当Ctrl+c对后台进程不起作用时就可以使用kill命令来给指定的进程发送2号信号也就是SIGINT信号也就是Ctrl+c,信号的处理方式为默认的也就是终止一个进程:
当输入一行命令"kill -2 6156"时按一下回车并没有结果,是因为当按下回车时要先一步回到bash等待用户输入下一条命令,这里并不希望命令的结果和用户输入的下条命令产生冲突显示错乱,因此要按两次回车才能看到进程被中断的结果;
除了kill函数还有一个函数raise函数,该函数可以给当前进程发送信号也就是自己给自己发送信号,这两个函数都是成功返回0,失败返回-1:
类似的abort函数是向当前进程发送6号信号也就是SIGABRT信号,