信号的阻塞:通过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. python3开发进阶-Django框架的中间件的五种用法和逻辑过程

    阅读目录 什么是中间件 中间件的执行流程 中间件的逻辑过程 一.什么是中间件? 官方的说法:中间件是一个用来处理Django的请求和响应的框架级别的钩子.它是一个轻量.低级别的插件系统,用于在全局范围 ...

  2. openresty的时间获取

    ngx.say('ngx.time()' .. ngx.time()) ngx.say('ngx.now()' .. ngx.now()) ngx.say('ngx.today()' .. ngx.t ...

  3. tomcat访问(access)日志配置、记录Post请求参数(转)

    一.配置与说明 tomcat访问日志格式配置,在config/server.xml里Host标签下加上 <Valve className="org.apache.catalina.va ...

  4. IIS8集成模式下打开静态资源被aspx处理程序处理,StaticFileModule失效问题分析

    问题描述: 打开js,css,jpg之类的静态资源文件触发了asp.net mvc的权限认证,并不是直接返回静态内容 问题分析: StaticFileModule 失效 ,可能是文件权限问题 问题解决 ...

  5. 关于MYsql 多字段排序

    SELECT switch_data.* , lan_data.ename FROM switch_data , lan_data WHERE switch_data.address = '佳合丽景' ...

  6. [转]SVN安装问题The Apache Portable Runtime (APR) library cannot be found

    http://blog.csdn.net/ckwer2008/article/details/47972601 Linux很多地方编译的时候都会用到apr 如果找不到apr就会报错 configure ...

  7. 我们知道写入过程比ZooKeeper集合中的读取过程要贵,因为所有节点都需要在数据库中写入相同的数据。因此,对于平衡的环境拥有较少数量(例如3,5,7)的节点比拥有大量的节点要好。

    我们知道写入过程比ZooKeeper集合中的读取过程要贵,因为所有节点都需要在数据库中写入相同的数据.因此,对于平衡的环境拥有较少数量(例如3,5,7)的节点比拥有大量的节点要好. 组件 描述 写入( ...

  8. ODATA4 及实现

    ODATA4 的JAVASCRIPT 实现:     http://jaydata.org/ ODATA4 的JAVA 项目  Apache Olingo:http://olingo.incubato ...

  9. JS 创建长度为100的数组,数值为角标

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  10. [Linux] ubuntu 格式化u盘

    $sudo fdisks -l 基本功,格式化命令,以格式化 /dev/sdb4 分区为例:$ sudo umount /dev/sdb4    # 必须先卸载该分区 # 格式化为 FAT 分区$ s ...