首先,先说明几个概念:
信号递达:实际执行信号的动作
信号未决:信号从产生到递达的状态
信号处理有三种情况:默认、忽略、用户自定义
每个信号都有三个表:block、pending、handler
block:表示信号是否被阻塞。用数据类型sigset_t存储的,0表示不被阻塞,1表示被阻塞。被阻塞的信号在产生时保持未决状态,直到进程解除对信号的阻塞,才执行递达的动作。
pending:未决标志。信号产生却没递达的为1,直到信号递达才清除该标志。用数据类型sigset_t存储的。
handler:存放的是信号处理函数的函数指针,默认是SIG_DEL、忽略是SIG_IGN。
信号处理过程:
执行main函数时发生中断或异常切换到内核态。中断处理完毕后从内核态返回用户态之前处理当前进程中可以递达(未决且未阻塞)的信号。如果是默认或忽略,处理之后直接返回main函数上下文执行。如果信号处理动作为自定义的信号处理函数则返回用户模式执行信号处理函数(不是回到主控制流,它们不存在调用与被调用的关系,是独立的控制流程),信号处理函数返回后自动执行特殊的系统调用sigreturn再次进入内核态。如果没有信号要递达,返回main函数的上下文继续执行。
信号集操作函数
int sigemptyset(sigset_t *set);//初始化信号集,对应bit位清零
int sigfillset(sigset_t *set);//初始化信号集,对应bit位置位
int sigaddset(sigset_t *set,int signo);//添加signo信号
int sigdelset(sigset_t *set,int signo);//删除signo信号
int sigismember(sigset_t *set,int signo);//判断信号集有效信号中是否包含signo信号