man文档描述:

sa_mask gives a mask of signals which should be blocked during execution of the signal handler. In addition, the signal which triggered the
handler will be blocked, unless the SA_NODEFER flag is used.

sigset_t sa_mask 是一个信号集,在调用该信号捕捉函数之前,将需要block的信号加入这个sa_mask,仅当信号捕捉函数正在执行时,才阻塞sa_mask中的信号,当从信号捕捉函数返回时进程的信号屏蔽字复位为原先值。
Q1:这个复位动作是sigaction函数内部处理,还是由调用者自己处理呢?

  由sigaction函数自动复位,不用我自己再去处理。

Q2:设置sa_mask的目的?

  在调用信号处理程序时就能阻塞某些信号。注意仅仅是在信号处理程序正在执行时才能阻塞某些信号,如果信号处理程序执行完了,那么依然能接收到这些信号。
在信号处理程序被调用时,操作系统建立的新信号屏蔽字包括正被递送的信号,也就是说自己也被阻塞,除非设置了SA_NODEFER。
因此保证了在处理一个给定的信号时,如果这种信号再次发生,通常并不将它们排队,所以如果在某种信号被阻塞时它发生了5次,那么对这种信号解除阻塞后,其信号处理函数通常只会被调用一次。

Q3:对于不同信号,当信号A被捕捉到并信号A的handler正被调用时,信号B产生了,
  3.1如果信号B没有被设置阻塞,那么正常接收信号B并调用自己的信号处理程序。另外,如果信号A的信号处理程序中有sleep函数,那么当进程接收到信号B并处理完后,sleep函数立即返回(如果睡眠时间足够长的话)
  3.2如果信号B有被设置成阻塞,那么信号B被阻塞,直到信号A的信号处理程序结束,信号B才被接收并执行信号B的信号处理程序。

    如果在信号A的信号处理程序正在执行时,信号B连续发生了多次,那么当信号B的阻塞解除后,信号B的信号处理程序只执行一次。
    如果信号A的信号处理程序没有执行或已经执行完,信号B不会被阻塞,正常接收并执行信号B的信号处理程序。
Q4:对于相同信号,当一个信号A被捕捉到并信号A的handler正被调用时
  4.1 又产生了一个信号A,第二次产生的信号被阻塞,直到第一次产生的信号A处理完后才被递送;
  4.2 如果连续产生了多次信号,当信号解除阻塞后,信号处理函数只执行一次。

没有设置SIGUSR2 阻塞的情况:

 #include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <signal.h>
#include <errno.h> #define BUFSIZE (1024) void sig_usr(int signo)
{
int nRemainSecond = ; if (signo == SIGUSR1)
{
printf("received SIGUSR1=%d\n", SIGUSR1);
nRemainSecond = sleep();
printf("over...nRemainSecond=%d\n", nRemainSecond);
}
else if (signo == SIGUSR2)
{
printf("received SIGUSR2=%d\n", SIGUSR2);
} } int main(int argc, char** argv)
{
int nSize = ;
char acBuf[BUFSIZE] = {};
struct sigaction act, oact;
sigset_t oldmask; act.sa_handler = sig_usr; sigemptyset(&act.sa_mask);
//sigaddset(&act.sa_mask, SIGUSR2);
sigaddset(&act.sa_mask, SIGQUIT);

act.sa_flags = |SA_INTERRUPT;
sigaction(SIGUSR1, &act, &oact);
signal(SIGUSR2, sig_usr);

while()
{
memset(acBuf, '\0', BUFSIZE);
nSize = read(STDIN_FILENO, acBuf, BUFSIZE);
if (errno == EINTR)
printf("interrupt, size=%d\n", nSize); if ( == nSize && acBuf[] == )
;
else if (nSize != -)
{
printf("nSize=%d, acBuf=%s", nSize, acBuf);
}
} return ;
}

result1:

首先,发送SIGUSR1给a.out,执行sig_usr(),在该函数执行期间,连续发送3次SIGUSR1信号,当第一次的SIGUSR1的sig_usr()执行完后,sig_usr()再执行一次;当第二次sig_usr()执行完后,read()中断返回,再次发送SIGQUIT信号时,依然能接收并正常退出。--->解释了Q4

result2:

首先,发送SIGUSR1给a.out,执行sig_usr(),在该函数执行期间,发送SIGUSR2(没有被设置成阻塞)并正常接收处理后,由于捕捉到SIGUSR2信号,SIGUSR1中的sleep()立即返回了,此时SIGUSR1的信号处理函数结束了。再发送一个SIGUSR1,在执行sig_usr()期间,发送一个SIGQUIT(被设置阻塞)信号,显然该信号被阻塞了,直到sig_usr执行完后,才递送SIGQUIT。--->解释了Q3。

最新文章

  1. API,框架,组件
  2. ebs history to look for password
  3. javaweb--上传文件使用灵活的自定义添加
  4. .net互转java 转行必备
  5. WebService的相关使用
  6. C++第五天学习
  7. mysql用户权限设置,远程访问设置、设置固定ip远程访问,设置root用户不能远程访问mysql数据库
  8. 通过百度地图API--获取全国地图的经纬度
  9. zookeeper常用指令
  10. windows系统快捷键
  11. windows 访问局域网共享文件
  12. maven的父工程中添加子工程
  13. 《Python黑帽子:黑客与渗透测试编程之道》 Web攻击
  14. chrome跨域访问
  15. 虚拟机上的Linux Java开发环境部署记录(VirtualBox+Ubuntu)第一章-基础环境搭建
  16. Oracle安装到Maven本地仓库
  17. bzoj1077
  18. FMX.Platform.TApplicationEvent
  19. Linux服务器access_log日志分析及配置详解(二)
  20. VC++6.0/MFC中如何限制Edit控件输入 例子,只能输入0和1

热门文章

  1. POJ 3537 Crosses and Crosses (NEERC)
  2. 【费用流】【Next Array】费用流模板(spfa版)
  3. windows下虚拟环境安装方法
  4. [TC-HouseProtection]House Protection
  5. 十. 图形界面(GUI)设计12.滚动条
  6. JAVA 按时间排序
  7. winform TreeView树节点上下移动
  8. 手把手教你调试Entity Framework 6源码
  9. 倍福TwinCAT(贝福Beckhoff)常见问题(FAQ)-Switch Case语句是否会自动跳转到下一个
  10. import * as obj from &#39;xx&#39;