信号基础知识
首先来说说,信号是什么?
信号可以理解为是一种“软中断”
信号可以使一个正在运行的进程被异步打断,然后转而去处理一个突发的事件。
常见的几种信号的意思
SIGHUP 关闭终端
SIGINT Ctrl+c
SIGQUIT Ctrl+\
SIGKILL 杀死进程
SIGPIPE 管道破裂
SIGALRM 超时
SIGCHLD 子进程死亡
产生信号的几种方式
- 按下终端
- 硬件异常
- kill
- 检测到,某种软件条件发生,时间到,管道破裂
信号的分类
对于信号的3种处理(响应)方式
1、缺省
2、忽略(有些信号不能被忽略,SIGKILL 、SIGSTOP)
3、捕获信号,按自己定义的方式去处理信号(SIGKILL 、SIGSTOP 也不能被捕获)
以上基础知识参考前面写的信号基础知识
信号在内核中的表示
每个信号都有两个标志位,分别表示阻塞(block)和未决(pending),还有一个函数指针指向信号处理动作
闹钟,定时器
看前面的信号练习闹钟,定时器
安装信号(signal&sigaction)
signal在信号练习的时候写过了,函数signal只能提供简单的信号安装操作,所以Linux提供了功能更强大的sigaction函数,此函数可用来检查和更改信号处理操作
int sigaction(int signum,
const struct sigaction *act,//要指定的信号处理方式
struct sigaction *oldact);//原来旧的信号处理方式
//用法:
struct sigaction act,oact;//先定义出结构体对象
act.sa_handler=myHandler;
sigemptyset(&act.sa_mask);
act.flags=0;
sigaction(SIGUSER1,&act,&oact);
捕捉信号(处理信号)
屏蔽信号
int sigprocmask(int how,
//SIG_BLOCK 让第二个参数set BLOCK上
//SIG_UNBLOCK 让第二个参数set 解除UNBLOCK
//SIG_SETMASK 让第二个参数set 不管原来什么样,对它SET成我们想设置的
const sigset_t *set, //我们要设置哪个信号的信号屏蔽
sigset_t *oldset); //这是个指针,返回来旧的信号屏蔽
运用:
int main()
{
sigset_t set;
sigemptyset(&set);
sigaddset(&set,...)
sigprocmask(SIG_BLOCK,&set,NULL);//屏蔽一个信号
...
sigprocmask(SIG_UNBLOCK,&set,NLL);//解除信号的屏蔽
}
sigset_t 是装信号的一个结构体类型,是一个内置类型
对信号集的操作
等待信号
pause函数
此函数将会挂起当前进程,直到接收到一个信号后才会恢复执行
执行进程后,进程就会阻塞,直到接收到Ctrl+c信号,然后执行处理函数,然后返回继续执行进程
sigsuspend函数
此函数其实和pause函数功能差不多,可以说是pause的加强版
运行结果是一样的
但,当然也有不同
它有比pause更强大的功能,可以信号切换
sigsuspend函数将当前进程屏蔽的信号集替换为自己参数的信号集,直到收到一个不在信号集中的信号后才继续执行进程,进程屏蔽的信号恢复为原来的
sigsuspend执行期间将自己的屏蔽2号信号覆盖屏蔽5好信号,sigsuspend执行完,又恢复为屏蔽5号信号
这就是信号切换,原本屏蔽5号,在一段时间内屏蔽2号,后,又恢复屏蔽5号