linux内核学习-信号-信号及信号处理

信号是一种软件终端,它提供一种处理异步事件的方法,也是进程同步的唯一方法。根据POSIX标准扩展的信号机制,不仅可以通知事件,还能传递数据。

一、信号来源:

1.硬件方式

  • 用户按了某些键,如ctrl+c,产生一个SIGINT信号
  • 硬件异常产生信号:除数为0,无效存储访问,

2.软件方式

  • kill命令
  • sigqueue函数
  • 某些软件发送的,如定时器

二、查看信号种类

使用明星kill -l查看系统支持的所有信号。
在这里插入图片描述
信号在signal.h中定义。
在这里插入图片描述
在这里插入图片描述在这里插入图片描述
1.可靠信号和不可靠信号
从UNIX系统集成的1~ 31号信号为不可靠信号。POSIX.4定义的33~64之间的为可靠信号。
在这里插入图片描述
2.信号优先级
信号的实质是软中断,中断有优先级,所以信号也有优先级。

三、捕捉信号

1.signal
源码

#include <stdio.h>
#include <signal.h>

void handler_sight(int signo)
{
	printf("recv SIGINT \n");
}

int main()
{
	signal(SIGINT,handler_sight );
	
	while(1)
	{
		;
	}
	
	return 0;
}

运行程序,按ctrl+c,就会触发信号。退出程序按ctrl+\

2.sigaction函数
这个函数可以用来检查或设置进程在接收到信号时的动作。
在这里插入图片描述
signum:函数需要操作的信号编号。可以是除SIGKILL和SIGSTOP以外的信号。
act:如果非空,则信号处理函数设置为act
oldact:如果非空,则就信号处理函数存储在oldact。

act和oldact是一个结构体sigaction。
在这里插入图片描述
源码如下:

#include <stdio.h>
#include <signal.h>

void handler_sight(int signo)
{
	printf("recv SIGINT \n");
}

int main()
{
	signal(SIGINT,handler_sight );
	
	while(1)
	{
		;
	}
	
	return 0;
}

运行程序

3.pause
线程执行pause后会挂起,直到遇到信号才会唤醒。
在这里插入图片描述

四、信号处理函数的返回

信号处理函数可以正常返回,也可以调用其他函数返回到程序的主函数中。
实现跳转的关键字是setjmp和longjmp
使用longjmp跳转到setjmp设置的位置。
在这里插入图片描述
参数env是一个特殊类型jmp_buf变量。是数组的一种,存放调用longjmp时能用来恢复栈状态的所有信息。一般来说说env是一个全局变量。

示例代码:
先上一个有问题的代码。最后看运行结果和分析


运行结果:
当发送第一次信号后,程序正常处理信号。但是在发送一次的时候,信号没反应了。原因是当第一次响应信号后,信号的屏蔽字被设置。如果信号正常返回,屏蔽字是会清除的,但是信号没有正常返回,而是执行了longjmp。解决方法有两种,手动清除屏蔽字和使用sigsetjmp/siglongjmp。

sigsetjmp/siglongjmp
在这里插入图片描述
和setjmp相比,多了savesigs参数。如果savesigs非零,则会自动清除屏蔽字。
实例代码如下

在这里插入代码片

运行结果

信号的发送
信号发送主要由函数kill 、raise 、sigqueue、alarm、settimer、abort完成。
kill
在这里插入图片描述
raise
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
这个可以实现微妙的闹钟。在这里插入图片描述
在这里插入图片描述

信号的屏蔽

sigsetops函数
在这里插入图片描述

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值