信号的阻塞:通过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的更多相关文章

  1. Linux进程间通信(二):信号集函数 sigemptyset()、sigprocmask()、sigpending()、sigsuspend()

    我们已经知道,我们可以通过信号来终止进程,也可以通过信号来在进程间进行通信,程序也可以通过指定信号的关联处理函数来改变信号的默认处理方式,也可以屏蔽某些信号,使其不能传递给进程.那么我们应该如何设定我 ...

  2. 信号之sigpending函数

    sigpending函数返回信号集,其中的各个信号对于调用进程是阻塞的而不能递送,因而也一定是当前未决的.该信号集通过set参数返回.(这些信号是已经产生的信号,但因为信号屏蔽字中对其设置了屏蔽位,从 ...

  3. ZT sigprocmask,sigpending函数

    sigprocmask,sigpending函数 分类: LINUX 2012-02-02 16:39 905人阅读 评论(0) 收藏 举报 signalredhatnulllinux [sigpro ...

  4. linux c编程:信号(三) sigprocmask和sigpending函数

    信号源为目标进程产生了一个信号,然后由内核来决定是否要将该信号传递给目标进程.从信号产生到传递给目标进程的流程图如下图所示: 进程可以阻塞信号的传递.当信号源为目标进程产生了一个信号之后,内核会执行依 ...

  5. sigprocmask, sigpending, sigsuspend的用法

    sigset_t set sigemptyset(&set) :清空阻塞信号集合变量 sigfillset(&set) :添加所有的信号到阻塞集合变量里 sigaddset(& ...

  6. sigprocmask , sigpending 和 sigsuspend函数

    转自 http://blog.csdn.net/elbort/article/details/7594772 sigprocmask函数:功能描述:设定对信号屏蔽集内的信号的处理方式(阻塞或不阻塞). ...

  7. Linux C 收藏

    某招聘要求:熟悉高性能分布式网络服务端设计开发,熟悉epoll.多线程.异步IO.事件驱动等服务端技术: <UNIX环境高级编程(第3版)>apue.h等源码文件的编译安装 <UNI ...

  8. linux c/c++

    string 字符串操作 操作数的都是 ( char * )型,操作数必须是指向字符串的指针("a"),不能是字符('a'),操作时不考虑末尾的'\0'. size_t strle ...

  9. 使用GDB 追踪依赖poco的so程序,core dump文件分析.

    前言 在windows 下 系统核心态程序蓝屏,会产生dump文件. 用户级程序在设置后,程序崩溃也会产生dump文件.以方便开发者用windbg进行分析. so,linux 系统也有一套这样的东东- ...

随机推荐

  1. [HDU5739]Fantasia(圆方树DP)

    题意:给一张无向点带有权无向图.定义连通图的权值为图中各点权的乘积,图的权值为其包含的各连通图的权和.设z_i为删除i点后图的权值,求$S = (\sum\limits_{i=1}^{n}i\cdot ...

  2. [BZOJ3944]Sum(杜教筛)

    3944: Sum Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 6201  Solved: 1606[Submit][Status][Discuss ...

  3. [Contest20180328]coin

    转化一下,相当于从$0$跳到$M$,每一步跳跃距离为$v_i$中的某个,每次跳跃距离不大于上一次,统计方案数 用$f_{i,j,k}$表示跳到$i$,第一步跳$v_j$,最后一步跳$\geq v_k$ ...

  4. 【博弈论】【SG函数】【找规律】Divide by Zero 2017 and Codeforces Round #399 (Div. 1 + Div. 2, combined) E. Game of Stones

    打表找规律即可. 1,1,2,2,2,3,3,3,3,4,4,4,4,4... 注意打表的时候,sg值不只与剩下的石子数有关,也和之前取走的方案有关. //#include<cstdio> ...

  5. 使用layer.js注意事项

    一.使用时,将layer整个文件夹放置你站点的任何一个目录,layer.js 开发版,layer.min.js 压缩版,引入其中一个即可.css等其它文件无需引入. 二.如果您的js引入是通过合并处理 ...

  6. IIS中使用Microsoft.Office.Interop.Excel 常见问题:RPC 服务器不可用。 (异常来自 HRESULT:0x800706BA) 的异常。等

    IIS中使用Microsoft.Office.Interop.Excel 异常1: 检索 COM 类工厂中 CLSID 为 {00024500-0000-0000-C000-000000000046} ...

  7. 【mybatis】mybatis 中update 更新操作,null字段不更新,有值才更新

    示例代码如下: <update id="updateGoodsConfigQuery" parameterType="com.pisen.cloud.luna.ms ...

  8. python获取系统信息,

    1 操作系统系统综合信息cur_sysinfo=platform.uname()浏览器信息cur_browserinfo=self.driver.capabilities['version']浏览器新 ...

  9. Win7用IIS发布网站系统 部署项目

    1.首先确保系统上已经安装IIS [控制面板]→[程序]→[程序和功能]→[打开或关闭Windows功能] 选中Internet 信息服务下面的所有选项,点击确定. 2. 获得发布好的程序文件 若没有 ...

  10. linux sudo使用学习记录

    sudo在linux中非常重要,它能够使普通的用户临时拥有root权限.但是如果让用户滥用sudo命令的话可能会造成严重的影响. 例如:修改root的密码,切换到root用户等等. 所以我们虽然需要赋 ...