Linux中的信号(1)

首先,我们来看一下Linux中都有那些信号:



每个信号都有一个编号和一个宏定义名称,这些宏定义可以在signal.h中找到。


然后来看一下产生信号的条件:
 
1. ⽤户在终端按下某些键时,终端驱动程序会发送信号给前台进程,例如Ctrl-C产生SIGINT信号,Ctrl-\产生SIGQUIT信号,Ctrl-Z产生SIGTSTP信号(可使前台进程停止,这个信号将在后面课程详细解释)。

2. 硬件异常产生信号,这些条件由硬件检测到并通知内核,然后内核向当前进程发送适当的信 号。例如当前进程执行了除以0的指令,CPU的运算单元会产生异常,内核将这个异常解释为SIGFPE信号发送给进程。再比如当前进程访问了非法内存地址,,MMU会产生异常,内核 将这个异常解释为SIGSEGV信号发送给进程。

3. 一个进程调用kill(2)函数可以发送信号给另一个进程。 可以用kill(1)命令发送信号 给某个进程,kill(1)命令也是调用kill(2)函数实现的,如果不明确指定信号则发送 SIGTERM信号,该信号的默认处理动作是终止进程。 当内核检测到某种软件条件发生时也可以通过信号通知进程,例如闹钟超时产生SIGALRM信号,向读端已关闭的管道写数据时产生 SIGPIPE信号。 如果不想按默认动作处理信号,用户程序可以调用sigaction(2)函数告诉内核如何处理某种信号。

进程收到信号的时候不是立即处理的,在合适的时候去处理它;在处理之前,先记录保存在自己的PCB中。

重点: 只要进程退出,意味着已经处理它

处理的方法有三种:1.忽略 2.执行该信号的默认动作 3.执行该信号的信号处理函数(catch捕捉一个信号)

通过什么可以产生信号呢?

A. 通过终端按键产生信号
B.调用系统函数向进程发信号

raise函数可以给当前进程发送指定的信号(自己给自己发信号)。
abort函数使当前进程接收到SIGABRT信号 而异常终止。

C.有软件条件产生信号

信号的结构:



如果在进程解除对某信号的阻塞之前这种信号产生过多次,将如何处理?POSIX.1允许系统递送该信号一次或多次。Linux是这样实现的:常规信号在递达之前产生多次只计一次,而实时信号在递达之前产生多次可以依次放在一个队列里。从上图来看,每个信号只有一 个bit的未决标志,非0即1,不记录该信号产生了多少次,阻塞标志也是这样表示的。因此,未决和阻塞标志可以用相同的数据类型sigset_t来存储,sigset_t称为信号集,这个类型可以表示每个信号的“有效”或“无效”状态,在阻塞信号集中“有效”和“无效”的含义是该信号是否被阻塞,而在未决信号集中“有效”和“无效”的含义是该信号是否处于未决状态。 阻塞信号集也叫做当前进程的信号屏蔽字(Signal Mask),这里的“屏蔽”理解为阻塞而不是忽略。

对于信号来说,不同的系统对其的构造略有不同,所以不能用位操作来改变他,应该用相应的信号集操作函数


函数sigemptyset初始化set所指向的信号集,使其中所有信号的对应bit清零,表示该信号集不包含任何有效信号。
函数sigfillset初始化set所指向的信号集,使其中所有信号的对应bit置位,表示 该信号集的有效信号包括系统支持的所有信号。
注意,在使用sigset_t类型的变量之前,一定要调用sigemptyset或sigfillset做初始化,使信号集处于确定的状态。
初始化sigset_t变量之后就可以在调用sigaddset和sigdelset在该信号集中添加或删除某种有效信号。这四个函数都是成功返回0,出错返回-1。
sigismember是一个布尔函数,⽤用于判断一个信号集的有效信号中是否包含某种信号,若包含则返回1,不包含则返回0, 出错返回-1。

信号捕捉

如果信号的处理动作是用户自定义函数,在信号递达时就调用这个函数,这称为捕捉信号。

由于信号处理函数的代码是在用户空间的,处理过程比较复杂,如下:
1. 用户程序注册了SIGQUIT信号的处理函数sighandler。 
2. 当前正在执行main函数,这时发生中断或异常切换到内核态。 
3. 在中断处理完毕后要返回用户态的main函数之前检查到有信号SIGQUIT递达。 
4. 内核决定返回用户态后不是恢复main函数的上下文继续执行,而是执行sighandler函数,sighandler和main函数使用不同的堆栈空间,它们之间不存在调用和被调用的关系, 是两个独立的控制流程。
5. sighandler函数返回后自动执行特殊的系统调用sigreturn再次进入内核态。 
6. 如果没有新的信号要递达,这次再返回用户态就是恢复main函数的上下文继续执行了。

信号的捕捉:(内核态的代码权限特别高。。。)



上方是用户态,下方是内核态。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值