SYNOPSIS
#include <signal.h> int sigemptyset(sigset_t *set); int sigfillset(sigset_t *set); int sigaddset(sigset_t *set, int signum); int sigdelset(sigset_t *set, int signum); int sigismember(const sigset_t *set, int signum);

以上都是信号集操作函数,如果是glibc,还额外提供了以下3个函数

       int sigisemptyset(sigset_t *set);

       int sigorset(sigset_t *dest, sigset_t *left, sigset_t *right);

       int sigandset(sigset_t *dest, sigset_t *left, sigset_t *right);

描述:

  查看linux3.13 signal.h文件源码,一共有31个用户可用的信号,信号集用每一位对应于一个信号。

  sigemptyset

    初始化信号集set,将指定的信号集set清空,即set的值为0。

  sigfillset

    初始化信号集set,将指定的信号集set全部置位,即set值为0x7FFFFFFF

  sigaddset

    将信号signum对应于信号集set的那一位置位

  sigdelset

    将信号signum对应于信号集set的那一位清零

  以上4个函数成功返回0,否则返回-1

  sigismember

    查询信号signum是否在信号集中置位了。如果置位了,返回1,否则返回0

 glibc的扩展信号集操作函数:

  sigisemptyset

    信号集set是否清空了

  sigorset

    获得信号集left,right的并集,存放到dest

  sigandset

    获得信号集left,right的交集,存放到dest

扩展函数的测试程序:

     sigset_t sigdest, sigleft, sigright;

     sigemptyset(&sigdest);
sigemptyset(&sigleft);
sigemptyset(&sigright); sigaddset(&sigleft, SIGALRM);
sigaddset(&sigleft, SIGINT); sigaddset(&sigright, SIGALRM);
sigaddset(&sigright, SIGQUIT); printf("\nSIG union\n");
sigorset(&sigdest, &sigleft, &sigright);
if ( sigismember(&sigdest, SIGALRM ) )
{
printf("SIGALRM\n");
}
if ( sigismember(&sigdest, SIGINT ) )
{
printf("SIGINT\n");
}
if ( sigismember(&sigdest, SIGQUIT ) )
{
printf("SIGQUIT\n");
} printf("\nSIG intersection\n");
sigemptyset(&sigdest);
sigandset(&sigdest, &sigleft, &sigright);
if ( sigismember(&sigdest, SIGALRM ) )
{
printf("SIGALRM\n");
}
if ( sigismember(&sigdest, SIGINT ) )
{
printf("SIGINT\n");
}
if ( sigismember(&sigdest, SIGQUIT ) )
{
printf("SIGQUIT\n");
}

运行结果:

SIG union
SIGALRM
SIGINT
SIGQUIT SIG intersection
SIGALRM

sigprocmask函数

SYNOPSIS
#include <signal.h> int sigprocmask(int how, const sigset_t *set, sigset_t *oldset);

根据动作how修改或者获取,或者修改并获取当前调用进程的信号掩码(一个信号集)。how有一下值可选:

       SIG_BLOCK
              将阻塞信号集设置为当前阻塞信号集oldset和指定的信号集的并集,相当于一个或操作

       SIG_UNBLOCK
              根据设置的信号集set,将当前阻塞信号集oldset对应的位清除,使其不阻塞。

       SIG_SETMASK
              将阻塞信号集设置为指定信号集set。

  •   如果oldset不为NULL,则函数返回时,oldset指向的内容为调用函数前进程信号掩码,也就是可以获取函数调用之前的信号掩码。
  •   如果set为NULL,则进程信号掩码不会更改,how将被忽略,如果此时oldset不为空,则可以获得之前的信号掩码。

需要注意的是sigprocmask只对单线程或者单进程有效,多线程中要使用thread_sigmask函数。还有就是SIGSTOP,SIGKILL是不会被阻塞的,即使指定了也会忽略。

  进程中的每个线程都有其各自独立的signal mask。

  子进程会获得父线程同样的signal mask。

sigpending
SYNOPSIS
#include <signal.h> int sigpending(sigset_t *set);

  sigpending,获得调用进程挂起的信号集,所谓挂起就是指有信号发往这个进程,但是此时被阻塞了,等阻塞解除,就会送至进程里面。

下面是一个综合的例子(来自APUE):

 static void sig_int(int signo)
{
printf("catch SIGINT\n");
if ( signal(SIGINT, SIG_DFL) == SIG_ERR )
{
perror("signal\n");
}
} int main ( int argc, char *argv[] )
{
sigset_t newset,oldset,pendmask; if ( signal(SIGINT,sig_int) == SIG_ERR )
{
perror("signal\n");
} if ( sigemptyset(&newset) < )
{
perror("sigempty\n");
} if ( sigaddset(&newset, SIGINT) < )
{
perror("sigaddset\n");
} if ( sigprocmask(SIG_BLOCK, &newset, &oldset) < )
{
perror("sigprocmask\n");
}
printf("\nSIGINT block\n"); sleep(); if ( sigpending(&pendmask) < )
{
perror("sigpending\n");
} if ( sigismember(&pendmask, SIGINT) )
{
printf("SIGINT is pendding\n");
} if ( sigprocmask(SIG_SETMASK, &oldset, NULL) < )
{
perror("sigprocmask\n");
}
printf("\nSIGINT unblock\n"); sleep();
return ;
}

  在进入第一次睡眠前,设置好了信号掩码,SIGINT将被阻塞,若在唤醒前按下ctrl+c(发送SIGINT),不会进行任何响应,事实上,如果不进行阻塞的话,收到任何信号将会唤醒sleep。等到第二次调用sigprocmask将signal mask恢复,则之前的那个SIGINT就会被响应,再次按下ctrl+c,int立马解除了第二个sleep。

运行结果:

SIGINT block
^C^C <----------此处阻塞了
SIGINT is pendding
catch SIGINT SIGINT unblock
^C <------------此处立马响应

并且可以看到,第一次连续发了2个SIGINT但是下面只响应了一次,说明阻塞的信号并不会在一个阻塞队列里面。

sigemptyset,sigfillset,sigaddset,sigdelset,sigismember,sigprocmask,sigpendmask作用的更多相关文章

  1. 信号处理篇alarm ferror kill mkfifo pause pclose perror pipe popen sigaction sigaddset sigdelset sigemptyset signal sleep strerror

    alarm(设置信号传送闹钟) 相关函数 signal,sleep 表头文件 #include<unistd.h> 定义函数 unsigned int alarm(unsigned int ...

  2. Linux信号

    信号本质上就是一个软件中断,它既可以作为两个进程间的通信的方式, 更重要的是, 信号可以终止一个正常程序的执行, 通常被用于处理意外情况 ,* 信号是异步的, 也就是进程并不知道信号何时会到达 $ki ...

  3. (八) 一起学 Unix 环境高级编程 (APUE) 之 信号

    . . . . . 目录 (一) 一起学 Unix 环境高级编程 (APUE) 之 标准IO (二) 一起学 Unix 环境高级编程 (APUE) 之 文件 IO (三) 一起学 Unix 环境高级编 ...

  4. [10]APUE:信号

    [a] 常用信号 SIGABRT 调用 abort 函数时产生此信号,进程异常终止 SIGALRM 调用 alarm 或 setitimer 函数超时之后产生 SIGCHLD 子进程终止或 stop ...

  5. VxWorks 6.9 内核编程指导之读书笔记 -- Singnals

    Signals 信号是操作系统用于异常处理和异步控制流的关键.在很多方面,信号相当于软件方面的硬件中的中断.操作系统产生的信号包括总线错误和浮点处理异常.信号也提供了API来管理和产生信号.在应用程序 ...

  6. 信号处理函数(2)-sigismember()

    定义: int sigismember(const sigset_t *set,int signum);   表头文件: #include<signal.h>   说明: sigismem ...

  7. linux中脚本扑捉(trap)信号问题

    扑捉ctrl+c信号: #!/bin/bash trap ; function trap() { echo "You press Ctrl+C."; echo "Exit ...

  8. [Linux]信号集和sigprocmask信号屏蔽函数

    一.概述 系统提供这样一种能力,就是创建一个信号集,然后传递给信号屏蔽函数,从而屏蔽向该进程发送的信号. 有一点需要注意的是,不能屏蔽SIGKILL和SIGSTOP信号. 信号集是sigset_t类型 ...

  9. sigsuspend sigprocmask函数的用法

    一个进程的信号屏蔽字规定了当前堵塞而不能递送给该进程的信号集.调用函数sigprocmask能够检測或更改其信号屏蔽字,或者在一个步骤中同一时候运行这两个操作. #include <signal ...

随机推荐

  1. Configuring a Windows Azure Project

    A Windows Azure project includes two configuration files: ServiceDefinition.csdef and ServiceConfigu ...

  2. javaweb学习总结(三十二)——JDBC学习入门

    一.JDBC相关概念介绍 1.1.数据库驱动 这里的驱动的概念和平时听到的那种驱动的概念是一样的,比如平时购买的声卡,网卡直接插到计算机上面是不能用的,必须要安装相应的驱动程序之后才能够使用声卡和网卡 ...

  3. mvc、mvp、mvvm使用关系总结

    MVC MVC全名是Model View Controller,是模型(model)-视图(view)-控制器(controller)的缩写,一种软件设计典范,用一种业务逻辑.数据.界面显示分离的方法 ...

  4. java初始化构造函数调用顺序

    类初始化时构造函数调用顺序: (1)初始化对象的存储空间为零或null值:  (2)调用父类构造函数:  (3)按顺序分别调用类成员变量和实例成员变量的初始化表达式:  (4)调用本身构造函数. 例子 ...

  5. ExecutorService常用方法和newFixedThreadPool创建固定大小的线程池

    1.ExecutorService: 是一个接口,继承了Executor: public interface ExecutorService extends Executor { } 2.Execut ...

  6. jquery 全选 全不选 反选

    1.概述 在项目中经常遇到列表中对复选框进行勾选操作,全选...反选.. 2. example <html> <body> <form id="test-for ...

  7. Java学习笔记之_JDBC

    JDBC简介 1.SUN公司为了简化,统一数据库的操作,定义了一套Java操作数据库的规范,称之为JDBC 2.数据库驱动 3.JDBC全称为:JAVA DataBase Commectivity(j ...

  8. ASP.NET本质论第一章网站应用程序学习笔记2

    1.初步走进ASP.NET 上篇笔记我们讲述了服务器监听问题,这篇我们就要讲述具体的请求处理了,ASP.NET所涉及的类大多数定义在System.Web程序集中. 在.NET中,程序集管理的最小逻辑单 ...

  9. bootstrap 学习笔记

    bootstrap作为当下的流行框架不知道它怎么能行呢? 之前也看过好多bootstrap的网上教程,可是发现光看真的记不住,说起来也真是忧桑~重点还是要自己做才是真正的印象深刻.后来我发现解析模板是 ...

  10. Spark中的RDD操作简介

    map(func) 对数据集中的元素逐一处理,变为新的元素,但一个输入元素只能有一个输出元素 scala> pairData.collect() res6: Array[Int] = Array ...