Linux---信号(二)

信号的三个阶段  

一、阻塞信号

1.信号的其他相关概念

实际执行信号的处理动作称为信号递达(Delivery)。

信号从产生到递达之间的状态,称为信号未决(Pending)。本质是这个信号被暂存在task_struct信号位图中,未决。

进程可以选择阻塞 (Block )某个信号。本质是OS允许进程暂时屏蔽指定的信号。1.该信号依旧是未决的。2.该信号不会被传递,直到解除堵塞方可传递。

被阻塞的信号产生时将保持在未决状态,直到进程解除对此信号的阻塞,才执行递达的动作。注意,阻塞和忽略是不同的,只要信号被阻塞就不会递达,而忽略是在递达之后可选的一种处理动作。

 2.信号集操作函数

#include <signal.h>
//初始化set所指向的信号集,使其中所有信号的对应bit清零,表示该信号集不包含任何有效信号。
int sigemptyset(sigset_t *set);
//初始化set所指向的信号集,使其中所有信号的对应bit置位,表示该信号集的有效信号包括系统支持的所有信号。
int sigfillset(sigset_t *set);
int sigaddset (sigset_t *set, int signo);
int sigdelset(sigset_t *set, int signo);
int sigismember(const sigset_t *set, int signo); 
//这四个函数都是成功返回0,出错返回-1。sigismember是一个布尔函数,用于判断一个信号集的有效信号中是否包含某种信号,若包含则返回1,不包含则返回0,出错返回-1。

sigprocmask

修改的是block表

//调用函数sigprocmask可以读取或更改进程的信号屏蔽字(阻塞信号集)。
//修改的是进程的block位图

#include <signal.h>
int sigprocmask(int how, const sigset_t *set, sigset_t *oset); 
//set 输入型     oset 输出型
//返回值:若成功则为0,若出错则为-1 

sigpending

不对pending做修改,而只是单纯的获取进程的pending。

如果我的进程预先屏蔽2号信号,不断地获取当前进程的Pending位图并不断打印,然后手动发送2号信号,因为2号信号不会被递达,打印的Pending位图有一位会被置1。

#include <signal.h>
sigpending(sigset_t *set);
读取当前进程的未决信号集,通过set参数传出。调用成功则返回0,出错则返回-1。 

二、捕捉信号

1.内核如何实现信号的捕捉

简化模型

2.sigaction

#include <signal.h>

int sigaction(int signo, const struct sigaction *act, struct sigaction *oact);

sigaction函数可以读取和修改与指定信号相关联的处理动作。调用成功则返回 0,出错则返回 - 1。signo是指定信号的编号。若act指针非空,则根据act修改该信号的处理动作。若oact指针非空,则通过oact传出该信号原来的处理动作。act和oact指向sigaction结构体。

将sa_handler赋值为常数SIG_IGN传给sigaction表示忽略信号,赋值为常数SIG_DFL表示执行系统默认动作。

代码演示

 #include<stdio.h>
 #include<string.h>
 #include<signal.h>
 #include<unistd.h>
 
 void handler(int signo){
     printf("get a signo:%d\n", signo);
 }
 
 int main(){
   struct sigaction act;
   memset(&act, 0, sizeof(act));
   act.sa_handler = handler;
 
   // 本质是修改当前进程的handler函数指针数组的特定内容
   sigaction(2, &act, NULL);
   while(1){
     printf("Hello.\n");
     sleep(1);
   }
   return 0;
 }          

注:当某个信号的处理函数被调用时,内核自动将当前信号加入进程的信号屏蔽字,当信号处理函数返回时自动恢复原来的信号屏蔽字,这样就保证了在处理某个信号时,如果这种信号再次产生,那么它会被阻塞到当前处理结束为止。如果在调用信号处理函数时,除了当前信号被自动屏蔽之外,还希望自动屏蔽另外一些信号,则用sa_mask字段说明这些需要额外屏蔽的信号,当信号处理函数返回时自动恢复原来的信号屏蔽字。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值