实时信号支持排队等待,而非实时的不可靠信号仅保留1个信号位.
sig_queue_recv.cpp 验证实时信号支持排队,非可靠信号不支持排队. SIGRTMIN为实时信号,SIGINT为非可靠信号. 程序运行后kill -RTMIN 多次,kill -INT 多次.然后执行kill -USR1 解除对RTMIN和INT的阻塞.打印RTMIN多次,而INT仅有一次.
sig_queue_unblock.cpp 主函数设置阻塞,主函数解除阻塞.
另外,注意在信号处理函数中解除对主函数设置的阻塞时,仅仅把之前阻塞的信号处理,而处理完成之后这些信号依然是阻塞的.即在信号处理函数无法彻底解除在主函数. 此问题在此处https://www.mkssoftware.com/docs/man3/sigprocmask.3.asp有解释,在信号处理函数中调用sigprocmask,信号处理函数返回后,会撤销sigprocmask的所做的事情,将恢复原来未决信号的掩码.
内核中的信号处理流程包含: 阻塞位,未决位,信号处理. 记住,所有关于信号的操作都是在信号未被阻塞时发生.即信号一旦被阻塞,那么信号的忽略/处理等操作将都暂时不会发生.
在信号处理函数中调用sigprocmask,仅仅修改的是未决位,而非修改阻塞位,这也就能解释为什么解除了阻塞但是却仅仅生效了一次.
man 7 signal记录了更多关于信号的基本理论,包含: 每个信号的默认行为介绍; 可发送信号的函数; 等待信号的函数;(等待信号阻塞) 同步接收信号的函数; 信号掩码和未决信号; 标准信号;(Linux中实现了POSIX中描述的可靠信号) 实时信号;(实时信号有如下特征:排队处理,保证处理顺序,可携带额外信息) 异步信号安全函数;(可在信号处理函数中安全调用的函数,此处的安全指行为可确定,而非安全的函数在被中断时行为时不可预知的) 系统调用和库函数被信号处理程序中断产生的行为; 系统调用和库函数被进程的暂停信号中断产生的行为;
参考: https://blog.csdn.net/jnu_simba/article/details/8947652 https://blog.csdn.net/jnu_simba/article/details/8944982