进程信号
默认处理方式调用的函数与忽略处理方式调用的函数都是系统中已经实现的----内核中直接处理
自定义信号处理方式:用户自己写一个事件处理函数;
在内核中有一个信号处理动作数组
信号的阻塞:并不是不接收信号。信号依旧可以注册,只是表示哪些信号暂时不处理
在PCB中有一个位图,位图叫block----阻塞信号集合;这个集合中的信号如果来了(添加到pending位图)则暂时不处理
如何阻塞一个信号:
0.将一些信号的处理函数自定义;1.将所有信号都给阻塞;2.在解除阻塞之前,给进程发送信号;3.解除阻塞,查看信号的处理情况;
int sigprocmask(int how, sigset_t* set, sigset_t* old)
how 参数列表:
1. SIG_BLOCK ---- 将set集合中的信号添加到内核中的block阻塞信号集合中,使用old保存原来的阻塞信息以便还原——阻塞set集合中的信号
2. SGI_UNBLOCK----将set集合中的信号从内核block阻塞信号集合中释放移除——对set集合中的信号解除阻塞
3. SGI_SETMASK----将内核中的block阻塞信号集合内容设置为set信号集合中的信息——阻塞set集合中的信号
eg:
SIG_BLOCK----set | block ——0001 | 1000 -> 1001;
SIG_UNBLOCK----~set & block —— 0001 | 1001 -> 1000;
SIG_SETMASK ---- block = set —— 0001 | 1001 -> 0001;
int sigmptyset(sigset_t* set)
----清空set信集合—使用一个变量的时候的初始化过程
int sigaddset(sigset_t* set, int signum)
----向set集合中添加指定信号
int sigfillset(sigset_t* set)
----将所有信号添加到set集合
int sigdelset(sigset_t* set, int signum)
----向set集合中移除指定信号
int sigismember(const sigset_t* set, int signum)
----判断指定信号是否在set集合
#include<stdio.h>
#include<unistd.h>
#include<stdlib.h>
#include<signal.h>
void sigcb(int signo){
printf("recv a signal:%d\n", signo);
}
int main(){
signal(SIGINT, sigcb);
signal(SIGRTMIN+4, sigcb); //定义了两个自定义回调
sigset_t set;
sigemptyset(&set); //清空集合,防止未知数据造成影响
sigfillset(&set); //向set集合中添加所有信号;
sigprocmask(SIG_BLOCK, &set, NULL); //阻塞set中的所有信号
printf("press enter continue\n");
getchar();
sigprocmask(SIG_UNBLOCK, &set, NULL); //解除set集合中的信号阻塞
while(1){
sleep(1);
}
return 0;
}
在所有信号中,有两个信号比较特殊,SIGKILL -9 / SIGSTOP -19这两个信号不可被阻塞,不可被忽略,不可被定义。