Linux下的信号是一个什么概念呢。我们在现实生活中也遇到过信号之类的。比如红绿信号灯,班主任叫你去办公室并且脸色不好,诸如此类的都会给你一个信号。让你辨别事情的发生。同样,Linux下也有许多的信号,让你执行相应的操作。比如我们经常使用的ctrl + c,ctrl + z,ctrl + d等,想结束掉当前的进程,我们通常使用ctrl + c,但是ctrl+c只适用于前台进程,如果是切换到后台进程的话,ctrl+c就终止不了。
我们写了一个死循环的输出“hello world”的例子,当我们使用ctrl+c的时候,相当于触发了2号信号来中断进程,当我们把它放到后台运行的时候,使用ctrl+c根本不管用。因为它信号只能对前台进程这样操作。
那么我们怎么终止它呢。这些信号里边有特殊的信号是可以终止后台进程的,9号信号(SIGKILL),这就是kill信号的强大之处。(如果所有的进程都放在后台,且都终止不了,那操作系统不得挂掉啊^_^哈哈)当然不只是9号信号可以对后台进程操作,还有些也可以。只是9号信号大家经常用到。所以就多说几句哈。(这里还要强调的一点是,shell不仅可以运行一个前台进程,还可以运行任意多个后台进程)
比如:
通过命令Kill -l,可以查看信号:
以上就是62个信号,其中1-31为普通信号,34-64为实时信号。
上面说了1-31号为普通信号,那么它可以用什么来表示呢。1和31这个敏感的数字,我们可以想到什么呢。是不是可以想到位图。32个比特位,每一位表示一个信号存在或者不存在。这样的话就只需要4个字节(也即一个整数)就可以存放这些信号了。
信号的处理动作主要有:
1.忽略该信号
2.执行该信号的默认处理动作
3.捕捉信号(自定义动作,自己定义的一些信号处理函数)
对于捕捉自定义信号,举个栗子哈:
当我们触发到2号信号时,我们就会执行自定义的信号处理函数,会打印出pid和sig值。而不再是终止进程。
结果如下:
小姿势(哈哈):
信号具有异步的特点,主要体现在任何一个时刻都可能产生信号。
那么话题又来了,产生信号的条件有哪些呢?
(1)像刚刚产生的信号,是用键盘产生的。键盘按ctrl+c,ctrl+z,ctrl+d等等。
(2)还有可能是因为某一个异常触发了某一个信号导致的。
比如上述这个题目,本来除数不能为0,这里让被除数除以一个为0的数,此时就会抛出异常。
这里的这个异常就是段错误所导致的。
(3)由于系统调用接口产生信号。系统调用接口,主要有以下几种:
1 .自己写一个kill 函数,来调用kill 函数或者直接调用系统的kill 函数使其产生9 号信号。
系统的kill :int kill (pid_t pid,int sig);
2 .调用raise函数,自己给自己发信号。
3 .调用abort函数,像exit 一样,触发捕捉信号后终止进程。
1.kill函数(成功返回0,错误返回-1)
运行结果为:运行完5个hello world之后,将执行2号信号,因此进程退出。
在这里,如何自己定义一个mykill函数呢。
它会检测你命令行上输入的命令,如果错误,将会给你显示出kill的正确用法。
上述用法错误,给你提示了。
比如先启动一个进程:(本身是死循环)
然后我们将其杀死:(通过获取进程号,这样就模拟了系统的kill函数)
2.使用raise函数(成功返回0,错误返回-1)
此时,结果与上述一样,只是raise为自己给自己发送2号信号。
3.使用abort函数(函数总会成功,所以没有返回值)
运行结果为:
(4)通过软件触发产生信号。主要使用alarm函数来触发SIGALRM信号。
unsigned int alarm(unsigned int seconds);
参数为秒数,多少秒之后触发SIGALRM信号。
这个例子当3秒之后触发alarm信号,终止进程