sigprocmask函数:

功能描述:
设定对信号屏蔽集内的信号的处理方式(阻塞或不阻塞)。

用法:
#include <signal.h>

int sigprocmask(int how, const sigset_t *set, sigset_t *oldset);

NOTE: If oldset is non-null, the previous value of the signal mask is stored in oldset.
参数:
how:用于指定信号修改的方式,可能选择有三种

SIG_BLOCK //加入信号到进程屏蔽。
SIG_UNBLOCK //从进程屏蔽里将信号删除。

SIG_SETMASK //将set的值设定为新的进程屏蔽。

相应函数命令:

sigset_t set

sigemptyset(&set) :清空阻塞信号集合变量

sigfillset(&set) :添加所有的信号到阻塞集合变量里

sigaddset(&set,SIGINT):添加单一信号到阻塞信号集合变量

sigdelset(&set,SIGINT):从阻塞信号集合变量中删除单一信号

sigismember(&set,int signum):这个函数测试信号signum是否包含在信号集合set中,如果包含返回1,不包含返回0,出错返回-1。错误代码也只有一个EINVAL,表示signum不是有效的信号代码。

代码说明:最简单的一个例子

#include <stdio.h>
#include <signal.h>

int main()

{
        sigset_t set;             //定义阻塞信号集的变量
        sigemptyset(&set);        //清空变量set的阻塞信号
        sigaddset(&set,SIGINT);   //添加将要阻塞的信号"SIGINT"到阻塞信号集变量
        sigdelset(&set,SIGINT);   //从已有的阻塞信号集变量中删除阻塞信号"SIGINT"
        sigaddset(&set,SIGQUIT);  //添加将要阻塞的信号"SIGQUIT"到阻塞信号集变量
        sigprocmask(SIG_SETMASK,&set,NULL);// 将当前的阻塞信号集合变量set设置为该进程信号阻塞列表
        while(1);                 //
        return 0;
}

结果显示:

[elbort@elbort test1]$ ./test
^\^\
^C
[elbort@elbort test1]$

说明: ^\   键盘上是ctrl + \  对应信号 SIGQUIT

^c  键盘上是ctrl + c 对应信号 SIGINT

该结果说明test进程屏蔽了信号SIGQUIT,没有屏蔽信号SIGINT。

sigpending 函数:

功能:返回在阻塞期间接收到阻塞信号的集合。

代码说明:

#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <unistd.h>

int main( void )
  {
    sigset_t set, oset, pset;

sigemptyset( &set );
    sigaddset( &set, SIGINT );
    sigaddset(&set,SIGQUIT);
    sigaddset(&set,SIGABRT);
    sigprocmask( SIG_BLOCK, &set, &oset );
    printf( "Old set was %8.8ld.\n", oset );
    printf( "set is %8.8ld.\n", set );

sigpending( &pset );
    printf( "Pending set is %8.8ld.\n", pset );

kill( getpid(), SIGINT );
    sigpending( &pset );
    printf( "Pending set is %8.8ld.\n", pset );

kill( getpid(), SIGQUIT );
    sigpending( &pset );
    printf( "Pending set is %8.8ld.\n", pset );

kill( getpid(), SIGABRT );
    sigpending( &pset );
    printf( "Pending set is %8.8ld.\n", pset );

//    sigprocmask( SIG_UNBLOCK, &set, &oset );

if(sigismember(&pset,SIGINT) == 1)
    {
        printf("SIGINT was came.\n");
    }
    if(sigismember(&pset,SIGQUIT) == 1)
    {
        printf("SIGQUIT was came.\n");
    }
    if(sigismember(&pset,SIGABRT) == 1)
    {
        printf("SIGABRT was came.\n");
    }
    /* The program terminates with a SIGINT */
    return( EXIT_SUCCESS );
 }

运行结果:

[elbort@elbort test1]$ ./test2
Old set was 00000000.
set is  00000038.
Pending set is 00000000.
Pending set is 00000002.
Pending set is 00000006.
Pending set is 00000038.
SIGINT was came.
SIGQUIT was came.
SIGABRT was came.
[elbort@elbort test1]$

注意:红色那句去掉//会得到完全不同的结果。为什么??

sigsuspend函数

功能:它有一套属于自己的屏蔽信号mask,能够选择性接收某些信号。在接收到可行信号(也即是没有被屏蔽的信号)之前,运行到它时,它会一直悬挂着,有点类似pause()函数。接受到可行信号后,它会退出悬挂并执行相应的信号函数。接收到的信号源:1.之前运行sigprocmask()函数中阻塞的信号;2.悬挂后接受到的信号。

代码说明:

Example:sigsuspend (Correct Way to Wait for Single Signal)

sigset_tmaskall, maskmost, maskold;

intsignum = SIGUSR1;

sigfillset(&maskall);

sigfillset(&maskmost);

sigdelset(&maskmost,signum);

sigprocmask(SIG_SETMASK,&maskall, &maskold);

sigsuspend(&maskmost);

sigprocmask(SIG_SETMASK,&maskold, NULL);

sigsuspend的整个原子操作过程为:
(1) 设置新的mask阻塞当前进程;
(2) 收到信号,恢复原先mask;
(3) 调用该进程设置的信号处理函数;
(4) 待信号处理函数返回后,sigsuspend返回。

具体例子说明:

#include <stdio.h>
#include <signal.h>
#include "unistd.h"

void fun_int()
{
   printf("\nsigsuspend catch SIGINT\n");
   printf("The sigsuspend already restore the old mask for sigprocmask.Now still in the signal handle,next will sleep 5 seconds you can press ctrl-c to test\n");
   sleep(5);
   return;
}
int main()
{
        sigset_t        set;
        sigfillset(&set);
        signal(SIGINT,fun_int);
        sigprocmask(SIG_SETMASK,&set,NULL);
        sigdelset(&set,SIGINT);
        printf("Here is the sigprocmask signal block,before use sigsuspend\n");
        sleep(5);
        printf("\nsleep over,next is sigsuspend\n");
        sigsuspend(&set);
        printf("\nI have return from the handler.I will sleep 5 seconds You can press ctrl-c to send sigint to test the mask of SIGINT restore from sigsuspend for sigprocmask\n");
        sleep(10);
        printf("\nTest finish\n");
        return 0;
}

结果显示:

1.sigsuspend 接收信号来源为sigprocmask() block期间接收到的信号

[elbort@elbort test1]$ ./test
Here is the sigprocmask signal block,before use sigsuspend
^\^\^\
^C^C^C
sleep over,next is sigsuspend

sigsuspend catch SIGINT
The sigsuspend already restore the old mask for sigprocmask.Now still in the signal handle,next will sleep 5 seconds you can press ctrl-c to test
^C^C^C
I have return from the handler.I will sleep 5 seconds You can press ctrl-c to send sigint to test the mask of SIGINT restore from sigsuspend for sigprocmask
^C^C^C^\^\^\
Test finish
[elbort@elbort test1]$

2.sigsuspend 接收信号来源为线程进入悬挂后接收的信号

[elbort@elbort test1]$ ./test
Here is the sigprocmask signal block,before use sigsuspend
^\^\^\^\^\
sleep over,next is sigsuspend
^\^\^\^\^\
^C
sigsuspend catch SIGINT
The sigsuspend already restore the old mask for sigprocmask.Now still in the signal handle,next will sleep 5 seconds you can press ctrl-c to test
^C^C^C^C^C
I have return from the handler.I will sleep 5 seconds You can press ctrl-c to send sigint to test the mask of SIGINT restore from sigsuspend for sigprocmask
^C^C^C^C^C^\^\^\
Test finish
[elbort@elbort test1]$

sigprocmask , sigpending 和 sigsuspend函数相关推荐

  1. sigprocmask, sigpending, sigsuspend的用法

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

  2. Linux信号实现精确到微秒的sleep函数:通过sigsuspend函数解决时序竞态问题

    原理就是先使用定时器定时,然后再使用pause函数或者sigsuspend函数主动阻塞挂起,最终恢复现场. 如果使用pause函数的话,优点是使用简单,缺点是有可能产生时序竞态,导致进程一直阻塞下去: ...

  3. sigsuspend函数(mysleep函数的改进)

    可以通过设置屏蔽SIGALRM的方法来控制程序执行逻辑,但无论如何设置,程序都有可能在"解除信号屏蔽"与"挂起等待信号"这个两个操作间隙失去cpu资源.除非将这 ...

  4. 信号驱动任务执行(pause、sigsuspend函数)

    信号驱动任务指的是通过信号来驱动任务的执行,每发送一次信号,任务就执行一次.实现该目的所需的函数就是 pause 或者 sigsuspend,pause和sigsuspend函数可以暂停当前进程,直至 ...

  5. Unix/Linux编程:竞态条件与sigsuspend函数

    利用pause和alarm函数实现sleep #include <unistd.h>int pause(void); pause函数使调用进程挂起直到有信号到达.如果信号的处理动作是终止进 ...

  6. sigsuspend()函数 解释

    sigsuspend函数作用 :如果在等待信号发生时希望去休眠,则使用sigsuspend函数是非常合适的 头文件:#include <signal.h> 一个保护临界区代码的错误实例:( ...

  7. 10.16 sigsuspend函数

    我们已经学习了如何修改进程的信号掩码,实现指定信号的阻塞与接触阻塞.我们可以使用这一技术来保护临界区域的代码(当在这一段区域内执行代码的时候哦,我们不希望被信号中断),但是如果我们想要接触一个信号的阻 ...

  8. sigsuspend()函数解决时序竞态问题

    sigsuspend解决时序竞态问题 使用pause()函数, 会导致在恢复信号集之前程序挂起 #include <unistd.h> #include <signal.h> ...

  9. sigsuspend 函数和 abort 函数

    pause 函数可以阻塞进程以等待一个信号的发生,但如果该信号是阻塞的,那么该信号的传递就会被推迟直到解除阻塞.对应用程序而言,就好像该信号发生在解除阻塞和 pause 之间(取决于内核如何实现信号) ...

最新文章

  1. 计算机应用基础电子演示文稿系统行考作业,最新电大计算机应用基础形考PowerPoint答案...
  2. 如何处理日志文件丢失
  3. new/delete与malloc/free的区别与联系详解
  4. mockito mock void方法_Spock如何模拟抽象类方法
  5. Hadoop赠品–综述
  6. 数据库杂谈(六)——数据库管理系统
  7. php如何查看上传的文件大小,PHP设置最大上传文件大小
  8. html flex 表单样式,Flexbox 布局的最简单表单的实现
  9. android-- apktool反编译工具使用详解
  10. 容量耦合系数模型_使用Fluent电芯仿真模型进行结构设计优缺点分析
  11. 自定义Popwindow
  12. 全渠道数字化营销平台
  13. 基于单片机的音乐盒系统设计(#0435)
  14. Intel CPU性能linpack测试
  15. 开上新能源车之后,如何摆脱“充电焦虑”?
  16. FreeRTOS-CortexM4-相关函数说明
  17. 通用流量办什么卡划算?告诉你三大运营商该如何选择?
  18. 程序员除了代码还应该有什么
  19. 5 RRC Measurement -- GAP
  20. 【bitset乱搞】BZOJ3687 简单题

热门文章

  1. 【文章】夏至——郭敬明
  2. android tv盒子哪个好用,2020什么电视盒子最好?超良心的三大实用选购技巧
  3. 记一次vue踩坑 this.$router.back()在ios失效,试了各种返回,最后发现是因为url传参的原因,去掉参数就可以了。。
  4. C语言自定义函数的调用
  5. Cisco忘了enable密码怎么办
  6. python中for循环在遍历文件内容时的问题
  7. django教程day05
  8. AUTOCAD——基线标注
  9. java网络学习之 PKCS标准 X.509标准 证书等概念 的汇总(16)
  10. 请编程实现求解s=1/(1*2)+1/(2*3)+1/(3*4)+……+1/(10*11),输出结果保留两位小数。