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, ...
随机推荐
- [BZOJ1502]月下柠檬树(自适应辛普森积分)
1502: [NOI2005]月下柠檬树 Time Limit: 5 Sec Memory Limit: 64 MBSubmit: 1387 Solved: 739[Submit][Status] ...
- 6.3(java学习笔记)缓冲流
一.缓冲流 使用缓冲流后的输入输出流会先存储到缓冲区,等缓冲区满后一次性将缓冲区中的数据写入或取出. 避免程序频繁的和文件直接操作,这样操作有利于提高读写效率. 缓冲流是构建在输入输出流之上的,可以理 ...
- TZOJ 删除前导多余的*号
描述 规定输入的字符串中只包含字母和*号,编写程序使字符串中前导的*号不得多于n个:若多于n个,则删除多余的*号:若少于或等于n个,则什么也不做,字符串中间和尾部的*号不删除. 输入 输入数据包括一串 ...
- 13南理工test01:进制转化
#include<iostream> #include<cstdlib> using namespace std; int main() { //cout<<5/2 ...
- Centos 6.5 优化 一些基础优化和安全设置
原文链接:http://www.centoscn.com/CentosSecurity/CentosSafe/2015/0424/5263.html 本文 centos 6.5 优化 的项有18处: ...
- ajaxfileupload-上传文件示例
1.引用文件 ajaxfileupload.js @{ ViewBag.Title = "数据导入"; Layout = "~/Views/Shared/_IndexLa ...
- debian6 安装VirtualBox的方法
方法一: 参考: https://www.virtualbox.org/wiki/Linux_Downloads 更新sources.list deb http://download.virtu ...
- Java汉字md5值不一致问题
原文:http://blog.csdn.net/earthhour/article/details/51188437 通过main方法测试得到一个加密值,通过servlet request调用得到一个 ...
- [Android Traffic] android 流量计算方法
android流量简介 流量统计文件:路径/proc/net/dev 打开文件,其中 lo 为本地流量, rmnet0 为3g/2g流量, wlan0 为无线流量. 在/sys/class/net/下 ...
- WebLogic Cluster Sevlet的配置
虽然生产环境中不建议使用,但因为客户需要考试可能用到,所以又做了一遍 1. 配置受管Server,ProxyServer,过程略 2.构建Proxy Application 建立一个ProxyApp的 ...