sigaction()之sa_mask
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。
sigaction()之sa_mask的更多相关文章
- signal()函数
转自:http://blog.csdn.net/sddzycnqjn/article/details/7285760 1. 信号概念 信号是进程在运行过程中,由自身产生或由进程外部发过来的消息(事件) ...
- pthread访问调用信号线程的掩码(pthread_sigmask )
掩码: 信号掩码 在POSIX下,每个进程有一个信号掩码(signal mask).简单地说,信号掩码是一个"位图",其中每一位都对应着一种信号.如果位图中的某一位为1,就表示在执 ...
- linux信号-------初涉
一.信号的本质 软中断信号(signal,又简称为信号)用来通知进程发生了异步事件.在软件层次上是对中断机制的一种模拟,在原理上,一个进程收到一个信号与处理器收到一个中断请求可以说是一样的.信号是进程 ...
- Linux程序设计学习笔记——异步信号处理机制
转载请注明出处: http://blog.csdn.net/suool/article/details/38453333 Linux常见信号与处理 基本概念 Linux的信号是一种进程间异步的通信机制 ...
- NIO 源码分析(05) Channel 源码分析
目录 一.Channel 类图 二.begin 和 close 是什么 2.1 AbstractInterruptibleChannel 中的 begin 和 close 2.2 Selector 中 ...
- Linux C--信号 sigaction函数
使用 sigaction 函数: signal 函数的使用方法简单,但并不属于 POSIX 标准,在各类 UNIX 平台上的实现不尽相同,因此其用途受 到了一定的限制.而 POSIX 标准定义的信号处 ...
- Linux 信号(三)—— sigaction 函数
ilocker:关注 Android 安全(新入行,0基础) QQ: 2597294287 #include <signal.h> int sigaction(int signo, con ...
- Linux进程间通信(一): 信号 signal()、sigaction()
一.什么是信号 用过Windows的我们都知道,当我们无法正常结束一个程序时,可以用任务管理器强制结束这个进程,但这其实是怎么实现的呢?同样的功能在Linux上是通过生成信号和捕获信号来实现的,运行中 ...
- sigaction和sigqueue
sigaction函数相对于siganl函数控制信号的发送要更加精确一些,其函数原型为: int sigaction(int signum, const struct sigaction *act, ...
随机推荐
- 【递归】【栈】先修课 计算概论(A)/函数递归练习(2)5:布尔表达式
总时间限制: 1000ms 内存限制: 65536kB 描述 输入一个布尔表达式,请你输出它的真假值. 比如:( V | V ) & F & ( F | V ) V表示true,F表示 ...
- 【强联通分量缩点】【最短路】【spfa】bzoj1179 [Apio2009]Atm
缩点后转化成 DAG图上的单源最长路问题.spfa/dp随便. #include<cstdio> #include<queue> #include<algorithm&g ...
- 【bzoj2142】【礼物】拓展Lucas定理+孙子定理
(上不了p站我要死了,侵权度娘背锅) Description 一年一度的圣诞节快要来到了.每年的圣诞节小E都会收到许多礼物,当然他也会送出许多礼物.不同的人物在小E 心目中的重要性不同,在小E心中分量 ...
- Entity Framework part2
EF原理以XML方式打开edmx文件,这个XML的文件主要包含两大部分:Runtime是类模型部分,Designer是VS中的图形界面重点讨论的是Runtime部分,又分为三大部分:SSDL数据模型部 ...
- python 实现汉诺塔问题
代码如下: def hano(n,x,y,z): if n==1: print(x,"->",z) else: #将n-1个盘子从x->y hano(n-1,x,z,y ...
- Git学习笔记(二) 远程仓库及分支
添加远程仓库(以GitHub为例) 所谓的远程仓库,其实就和本地仓库一样,只是我们本地电脑可能会关机什么的.远程仓库的目的就是保证7*24小时开启状态.GitHub是一个很好的公共Git远程仓库(后面 ...
- windbg学习—-.ecxr
.ecxr 命令定位当前异常的上下文信息,并显示指定记录中的重要寄存器 0:000> .ecxr eax=10000000 ebx=7ffd9000 ecx=77386500 edx=002 ...
- golang构造单链表
原文地址:http://www.niu12.com/article/47package main import "fmt" type ListNode struct { Value ...
- iOS:二维码的生成
所谓的二维码就是一个图片,只不过在iOS需要借用<CoreImage/CoreImage.h>来实现, 并且二维码图片是通过CIImage来转成UIImage的.具体步骤如下: // 1 ...
- 深度剖析OpenGL ES中的多线程和多窗口渲染技术
由 创新网小编 于 星期五, 2014-04-11 14:56 发表 移动设备中的CPU和GPU已经变得很强大,到处都是配备一个或多个高分辨率屏幕的设备,需要使用带有图形驱动器的复杂交互也日益增加.在 ...