Linux 修改信号的响应方式

修改信号的响应方式

1.signal()方法介绍:

修改信号的响应方式要用到方法signal()。需要引用头文件signal.h。signal()的原型:

在这里插入图片描述

typedef重命名了一个函数指针的类型,这个指针的类型为指向一个参数为int返回值为void的函数的指针。这个函数指针作为signal的返回值,也作为为signal的第二个参数,所以可以传入一个函数指针,即传入函数的地址,也就是函数名;signal第一个参数信号的代号,是整数值,所以是int型。signal方法表达的意思就是如果收到一个代号为signum的信号,该做出什么响应,就是用第二个参数handler来设置。

signal方法的第二个参数有三种,分别是默认、忽略和用户自定义:
默认:SIG_DFL,它实际上是把0强转成了一个(void(*)(int))类型的函数指针。
忽略:SIG_IGN,它实际上是把1强转成了一个(void(*)(int))类型的函数指针。
用户自定义:自己写的信号处理函数

2.用signal修改SIGINT信号的响应方式

在键盘上按下Ctrl+c时,会给当前终端前台执行的进程发送SIGINT信号

(1)给当前终端前台执行的进程发送SIGINT信号之后默认的响应方式

代码如下:

在这里插入图片描述

上述代码,是一个死循环,每一秒会输出一个hello。

编译并运行:

在这里插入图片描述
由结果可以看出,执行main程序之后会每隔一秒输出一个"hello",知道输入Ctrl+C之后该程序才会终止,该进程也就结束了。就是因为给当前终端前台执行的进程main发送了SIGINT信号,然后以默认方式响应,将进程结束。

也可以把代码修改为以下形式,编译和运行结果和上面的代码一样:

在这里插入图片描述

(2)给当前终端前台执行的进程发送SIGINT信号之后自定义的响应方式

代码如下:

在这里插入图片描述

代码分析:

代码顺序执行,上述代码14行的signal(SIGINT,sig_fun);其实是做了一个约定,这条代码中的signal也不是去调用SIGINT和sig_fun,而是把它两作为参数传给了signal,sig_fun什么时候调用由内核决定,因为sig_fun是一个回调函数,由用户编写但是不由用户来调用。signal()不是在while循环里面调用,而是内核调用,也就是说如果是SIGINT这个信号,内核就会帮忙调用sig_fun这个函数。改变了信号的响应方式,在给进程发送了SIGINT信号之后不再按照默认方式响应退出当前进程,而是去调用sig_fun()这个函数。当前进程在执行while循环的时候,接收到SIGINT这个信号之后while循环先暂停,内核就会帮忙去调用sig_fun这个函数,然后执行sig_fun这个函数的函数体,最后再恢复while循环的执行。

编译并运行的结果:

在这里插入图片描述

(3)给当前终端前台执行的进程发送SIGINT信号之后忽略的响应方式

代码如下:

在这里插入图片描述

编译并运行:

在这里插入图片描述

由结果可以看出,执行main程序之后,通过给当前终端前台执行的进程main发送SIGINT信号想要使进程结束的时候,并没有成功,是因为把SIGINT信号的响应方式修改成了忽略的方式,进程main将这个信号忽略掉继续执行,然后通过别的信号来终止这个程序。

(4)连续执行signal方法,该进程会以最后一次执行signal方法来响应这个信号

有以下代码:

在这里插入图片描述

在while循环中执行两次不同的signal方法,分别是忽略响应信号SIGINT和默认响应信号SIGINT。

编译并运行:

在这里插入图片描述

由结果可以看出,给正在执行的进程发送了两个SIGINT信号之后,当前进程会以最后一个SIGINT信号默认的响应方式对SIGINT信号进行响应。对于相同的信号来说,程序中最后的信号响应会把前面的信号响应覆盖掉。

(5)第一次发出SIGINT信号时,当前进程以用户自定义的方式对信号进行响应,第二次发出SIGINT信号时以默认方式对信号进行响应。

代码如下:

在这里插入图片描述

代码分析:

代码顺序执行,先执行15行代码signal(SIGINT,sig_fun),如果当前进程正在执行的时候发送信号SIGINT,这时会调sig_fun函数对该信号做出响应,打印这个信号的代号,打印完之后回到sig_fun函数中,sig_fun内部又执行了11行代码signal(SIGINT,SIG_DFL);,再一次向进程发出SIGINT信号时,就是以默认的方式响应该信号。

编译并运行的结果:

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值