信号的阻塞:通过sigprocmask()将信号集sigset_t中的信号设置为阻塞。SIG_BLOCK是指对相应信号的“递送阻塞”,内核在递送一个原来被阻塞的信号给进程时(而不是在产生该信号时),才决定对它的处理方式,那么进程在信号递送给它之前仍可改变对该信号的动作。

一个信号的"生命周期"为:产生(generation)、未决(pending)、递送(delivery)

如果将信号设置为阻塞,那么,在信号产生和递送之间的时间间隔内,称信号是未决的(pending)。

如果信号被设置成阻塞,且该信号的动作是系统默认动作或捕获该信号,当该信号产生后,则进程将此信号的状态保持为未决(pending)状态,直到对该信号解除了阻塞或将该信号的动作改为忽略。

sigpending函数的作用是获取被设置为SIG_BLOCK的信号集。

 static void sig_quit(int signo)
{
printf("111caught SIGQUIT\n");
if (signal(SIGQUIT, SIG_DFL)==SIG_ERR)
{
printf("can't reset SIGQUIT\n");
}
}
 int main(int argc, char** argv)
{
sigset_t newmask, oldmask, pendmask; if (signal(SIGQUIT, sig_quit) == SIG_ERR)
{
printf("can't catch SIGQUIT\n");
return -;
} //block SIGQUIT and save cureent signal mask
sigemptyset(&newmask);
sigaddset(&newmask, SIGQUIT); if (sigprocmask(SIG_BLOCK, &newmask, &oldmask) < )//阻塞SIGQUIT信号
{
printf("SIGBLCOK error\n");
return -;
}
printf("newmask:%x, oldmask:%x\n", newmask, oldmask); sleep(); if (sigpending(&pendmask)<)
{
printf("sigpending error\n");
return -;
}
printf("pendmask:%x\n", pendmask); if (sigismember(&pendmask, SIGQUIT))
printf("SIGQUIT pending\n"); if (sigprocmask(SIG_SETMASK, &oldmask, NULL))//解除阻塞
{
printf("sigprocmask error\n");
return -;
}
printf("222SIGQUIT unblock\n"); sleep(); return ;
}

运行结果为:

1. 当在第一个sleep 5s期间,Ctrl+\ 产生SIGQUIT信号时:

因为在sleep期间产生了SIGQUIT信号,那么此时该信号的状态时pending的,当该信号被设置为不阻塞后,即解除阻塞后,立即捕获该信号。从输出中可以看出,sig_quit中的printf语句先执行,然后再执行sigprocmask之后的printf语句。

2. 如果在第一个sleep 5s期间,不产生SIGQUIT信号,显然,sigpending的输出为0。

从结果中可以看到,本次pendmask为0,而上次pendmask为4。

SIG_BLOCK是指对相应信号的“递送阻塞”,内核在递送一个原来被阻塞的信号给进程时(而不是在产生该信号时),才决定对它的处理方式,那么进程在信号递送给它之前仍可改变对该信号的动作。

 static void sig_quit(int signo)
{
printf("111caught SIGQUIT\n");
if (signal(SIGQUIT, SIG_DFL)==SIG_ERR)
{
printf("can't reset SIGQUIT\n");
}
}
 static void sig_quit2(int signo)
{
printf("xxxcaught SIGQUIT\n");
if (signal(SIGQUIT, SIG_DFL)==SIG_ERR)
{
printf("can't reset SIGQUIT\n");
}
}
 int main(int argc, char** argv)
{
sigset_t newmask, oldmask, pendmask; if (signal(SIGQUIT, sig_quit) == SIG_ERR)
{
printf("can't catch SIGQUIT\n");
return -;
} //block SIGQUIT and save cureent signal mask
sigemptyset(&newmask);
sigaddset(&newmask, SIGQUIT); if (sigprocmask(SIG_BLOCK, &newmask, &oldmask) < )//阻塞SIGQUIT信号
{
printf("SIGBLCOK error\n");
return -;
}
printf("newmask:%x, oldmask:%x\n", newmask, oldmask); sleep(); if (signal(SIGQUIT, sig_quit2) == SIG_ERR)
{
printf("can't catch SIGQUIT\n");
return -;
} if (sigpending(&pendmask)<)
{
printf("sigpending error\n");
return -;
}
printf("pendmask:%x\n", pendmask); if (sigismember(&pendmask, SIGQUIT))
printf("SIGQUIT pending\n"); if (sigprocmask(SIG_SETMASK, &oldmask, NULL))
{
printf("sigprocmask error\n");
return -;
}
printf("222SIGQUIT unblock\n"); sleep(); return ;
}

运行结果为:

在line24中,又重新设置的SIGQUIT的信号处理程序。

如果信号被设置成阻塞,且该信号的动作是系统默认动作或捕获该信号,当该信号产生后,则进程将此信号的状态保持为未决(pending)状态,直到对该信号解除了阻塞或将该信号的动作改为忽略

 int main(int argc, char** argv)
{
sigset_t newmask, oldmask, pendmask; if (signal(SIGQUIT, sig_quit) == SIG_ERR)
{
printf("can't catch SIGQUIT\n");
return -;
} //block SIGQUIT and save cureent signal mask
sigemptyset(&newmask);
sigaddset(&newmask, SIGQUIT); if (sigprocmask(SIG_BLOCK, &newmask, &oldmask) < )//阻塞SIGQUIT信号
{
printf("SIGBLCOK error\n");
return -;
}
printf("newmask:%x, oldmask:%x\n", newmask, oldmask); sleep(); if (sigpending(&pendmask)<)
{
printf("sigpending error\n");
return -;
}
printf("pendmask:%x\n", pendmask); if (sigismember(&pendmask, SIGQUIT))
printf("SIGQUIT pending\n"); if (signal(SIGQUIT, SIG_IGN) == SIG_ERR)
{
printf("can't catch SIGQUIT\n");
return -;
}
printf("SIGQUIT IGNORE"); sleep(); return ;
}

运行结果为:

最新文章

  1. VS2013使用winsock.h和winsock2.h发生冲突后的终极解决方法
  2. 《JavaScript修炼之道》读书笔记
  3. K2 学习笔记
  4. Spark on Yarn遇到的问题及解决思路
  5. Win7中修改Chrome浏览器缓存文件目录
  6. lua编码转换
  7. Niagara技术文档汇总
  8. Windows Phone 8初学者开发—第21部分:永久保存Wav音频文件
  9. 用django创建一个简单的sns
  10. linux中ssh登录Permanently added (RSA) to the list of known hosts问题解决
  11. webapp填坑记录[更新中]
  12. PHP函数register_shutdown_function的用法
  13. Android倒计时器——CountDownTimer
  14. UOJ#370. 【UR #17】滑稽树上滑稽果 动态规划
  15. VS2017 EF本地数据库链接
  16. tensorFlow可以运行的代码
  17. 2017第八届蓝桥杯C/C++语言A组
  18. 25 个常用的 Linux iptables 规则
  19. Java + 腾讯邮箱 SSL加密问题 重要通知
  20. C#基础篇五值类型和引用类型

热门文章

  1. [BZOJ 1143] 祭祀river
  2. @RequestMapping注解的使用,Controller方法返回值
  3. python内建datetime模块
  4. Visio插入竖直省略号
  5. 基于CentOS与VmwareStation10搭建Oracle11G RAC 64集群环境:2.搭建环境-2.10.配置用户NTF服务
  6. Modify Headers模拟不同地域进行网页测试
  7. (原创)sklearn中 F1-micro 与 F1-macro区别和计算原理
  8. HA分布式集群一hadoop+zookeeper
  9. &amp;lt;十&amp;gt;读&amp;lt;&amp;lt;大话设计模式&amp;gt;&amp;gt;之观察者模式
  10. Ural 1260 A nudnik photographer(DP)