sigpending
信号的阻塞:通过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 ;
}
运行结果为:

sigpending的更多相关文章
- Linux进程间通信(二):信号集函数 sigemptyset()、sigprocmask()、sigpending()、sigsuspend()
我们已经知道,我们可以通过信号来终止进程,也可以通过信号来在进程间进行通信,程序也可以通过指定信号的关联处理函数来改变信号的默认处理方式,也可以屏蔽某些信号,使其不能传递给进程.那么我们应该如何设定我 ...
- 信号之sigpending函数
sigpending函数返回信号集,其中的各个信号对于调用进程是阻塞的而不能递送,因而也一定是当前未决的.该信号集通过set参数返回.(这些信号是已经产生的信号,但因为信号屏蔽字中对其设置了屏蔽位,从 ...
- ZT sigprocmask,sigpending函数
sigprocmask,sigpending函数 分类: LINUX 2012-02-02 16:39 905人阅读 评论(0) 收藏 举报 signalredhatnulllinux [sigpro ...
- linux c编程:信号(三) sigprocmask和sigpending函数
信号源为目标进程产生了一个信号,然后由内核来决定是否要将该信号传递给目标进程.从信号产生到传递给目标进程的流程图如下图所示: 进程可以阻塞信号的传递.当信号源为目标进程产生了一个信号之后,内核会执行依 ...
- sigprocmask, sigpending, sigsuspend的用法
sigset_t set sigemptyset(&set) :清空阻塞信号集合变量 sigfillset(&set) :添加所有的信号到阻塞集合变量里 sigaddset(& ...
- sigprocmask , sigpending 和 sigsuspend函数
转自 http://blog.csdn.net/elbort/article/details/7594772 sigprocmask函数:功能描述:设定对信号屏蔽集内的信号的处理方式(阻塞或不阻塞). ...
- Linux C 收藏
某招聘要求:熟悉高性能分布式网络服务端设计开发,熟悉epoll.多线程.异步IO.事件驱动等服务端技术: <UNIX环境高级编程(第3版)>apue.h等源码文件的编译安装 <UNI ...
- linux c/c++
string 字符串操作 操作数的都是 ( char * )型,操作数必须是指向字符串的指针("a"),不能是字符('a'),操作时不考虑末尾的'\0'. size_t strle ...
- 使用GDB 追踪依赖poco的so程序,core dump文件分析.
前言 在windows 下 系统核心态程序蓝屏,会产生dump文件. 用户级程序在设置后,程序崩溃也会产生dump文件.以方便开发者用windbg进行分析. so,linux 系统也有一套这样的东东- ...
随机推荐
- CodeChef - UASEQ Chef and sequence
Read problems statements in Mandarin Chinese and Russian. You are given an array that consists of n ...
- 【动态规划】【记忆化搜索】CODEVS 1011 数的计算 2001年NOIP全国联赛普及组
设答案为f(n),我们显然可以暴力地递归求解: f(n)=f(1)+f(2)+……+f(n/2). 但是n=1000,显然会超时. 考虑状态最多可能会有n种,经过大量的重复计算,所以可以记忆下来,减少 ...
- 【手动开栈】【dfs序】【树状数组】【Tarjan】bzoj2819 Nim
考虑树状数组区间修改(只对其子树的答案有影响)点查询,每个点记录的是它到根路径上的权值异或和. 答案时query(L)^query(R)^a[lca]. 这种方法在支持区间加法.减法的树上询问的时候可 ...
- 【强联通分量缩点】【最短路】【spfa】bzoj1179 [Apio2009]Atm
缩点后转化成 DAG图上的单源最长路问题.spfa/dp随便. #include<cstdio> #include<queue> #include<algorithm&g ...
- python3开发进阶-Django框架中form的查看校验方法is_valid()的源码,自定义验证方法
form表单的校验方法is_valid() 点开我们发现这个函数里面只有两个方法方法,最终返回True or False 我们点进.is_bound属性,里面判断传输的数据不是空和上传文件不是空 点进 ...
- Java高级架构师(一)第09节课:搭建基础的开发环境
- Java高级架构师(一)第05节:TortoiseGit的本地使用
- linux+iptables搭建网关服务器
公司购买的一批云服务器只带内网,配置了一个负载均衡器(lb),这批服务器通过lb可以对外提供服务,但是这批服务器不能主动连接外网,例如使用wget下载文件,或者curl访问ttlsa.com站点. 额 ...
- nginx+php简单配置环境
首先我的需求是: 1. 需要有PHP的服务.web目录存放在各处. 2. 需要有多个端口. 步骤: 1. 安装nginx php,我的系统是mac 所以安装使用brew, 一键完成... 2. 开启p ...
- 网络采集软件核心技术剖析系列(2)---如何使用C#语言获得任意站点博文的正文及标题
一 本系列随笔概览及产生的背景 本系列开篇受到大家的热烈欢迎,这对博主是莫大的鼓励,此为本系列第二篇,希望大家继续支持,为我继续写作提供动力. 自己开发的豆约翰博客备份专家软件工具问世3年多以来,深受 ...