信号及信号处理

1. 信号的初步认识

1.1 信号的特点

信号所携带的信息量少,操作简单

1.2 信号的状态

1.产生
①由键盘产生:例如Ctrl+c,Ctrl+
②命令:kill
③系统函数:kil
④软条件:定时器
⑤硬件:段错误,除0错误

由键盘和和硬件产生的信号统称为硬件方式,其余的为软件方式

2.未决状态
处在该状态的信号没有被处理。
3.递达状态
信号被处理。处理信号的方式如下:

  • 忽略
  • 捕捉
  • 执行了默认动作

信号是由内核发送的,优先级比较高。进程收到信号后,会暂停正在处理的事情,优先处理信号,处理完成之后继续原来的工作

1.3 处理方式

1.忽略信号,这是大多程序对信号的处理方式,但SIGKILL和SIGSTOP信号不能被忽略。这是为了最后能够有一种方式结束掉进程

2.捕捉信号,捕捉信号后可以做相应的一些处理

3.执行默认动作,大多数信号的默认动作为终止进程

1.4 产看信号

使用 kill -l 命令可以查看信号

2. 信号集

2.1 信号集的相关概念

1.未决信号集:没有被当前进程处理的信号

2.阻塞信号集:将某个信号放到阻塞信号集,这个信号就不会被进程处理,阻塞解除之后,信号被处理。

信号产生后,处于未决状态,进程受到信号后信号会被放入未决信号集中。在未决信号集中的信号等待被处理,进程会判断阻塞信号集中信号对应的标志位是否为1,如果为1不处理该信号,如果为0处理该信号
在这里插入图片描述
3.自定义信号集:用户可以使用自定义信号集对信号集进行操作。

相关处理函数如下:

  • 将set集合置空
int 	sigemptyset(sigset_t *set); 
  • 将所有信号加入set集合
int 	sigfillset(sigset_t *set); 
  • 将signo信号加入到set集合
int 	sigaddset(sigset_t, *set, int signo);
  • 从信号集中移除signo信号
int sigdelset(sigset_t *set, int signo);
  • 判断信号是否存在
int 	sigismember(const sigset_t *set, int signo);
  • 检测信号集是否为空
int 	sigisemptyset(const sigset_t *set); 
  • 按逻辑与方式将两个信号集并
int 	sigandset(sigset_t *set, const sigset_t *left, const sigset_t *right);

*按逻辑或方式将两个信号集并

int	 sigorset(sigset_t *set, const sigset_t *left, const sigset_t *right); 

sigprocmask函数

  • 屏蔽按到接触信号屏蔽,将自定义信号集设置给阻塞信号集
  • 函数原型:
int 	sigprocmask(int how, const sigset_t *set, sigset_t *oldset);

在这里插入图片描述

信号的捕捉

1.signal函数

typedef void (*sighandler_t)(int);
sighandler_t signal(
					int signum,    //要捕捉的信号
					sighandler_t handler //执行的动作
);

handler是一个函数指针,函数指向的类型为*sighandler_t,即它指向的函数有一个int型参数,返回类型为void

如果handler不是函数指针,就必须设置为SIG_IN(忽略该信号),SIG_DFL(执行默认动作)

2.sigaction函数:可以读取和修改与指定信号相关联的处理动作。

int sigaction(
                 int    signum, //捕捉的信号
                 construction 	struct sigaction 	*act,   //信号的处理函数
                 struct sigaction 	*oldact   //旧的信号处理函数被存储在这
);

/*sigaction结构体*/
struct sigaction {
               void     (*sa_handler)(int);   //信号的处理方式
               void     (*sa_sigaction)(int, siginfo_t *, void *);
               sigset_t   sa_mask;  //在信号处理函数执行过程中,临时屏蔽指定的信号,额外屏蔽
               int        sa_flags;  //通常设置为0
               void     (*sa_restorer)(void);  //不再使用
           };

处理方式:

  1. 若act为非空,则根据act结构体中的信号处理方式处理信号
  2. 若oldatc为非空,则根据原来的信号处理函数处理信号,根据act中的设置处理动作
  3. handler 的设置与上述signal的相同,如果handler不是函数指针,就必须设置为SIG_IN(忽略该信号),SIG_DFL(执行默认动作)

内核实现信号的捕捉

  1. 用户注册一个信号处理函数sighandler。
  2. 正在运行的程序,遇到中断、异常或是系统调用时进入内核态。
  3. 内核在处理完异常返回主函数之前,会检查有无信号未处理。检查到有信号未处理,并按照用户自定义的函数处理,如果没有自定义函数,则按照默认动作处理。
  4. 若设置了自定义处理函数,内核返回用户态执行sighandler函数
  5. 执行完sighandler函数后,执行系统调用sigreturn回到内核态
  6. 检查是否还有信号需要处理,如果没有就返回主程序继续主程序
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值