写在前面:小生纯业余选手,开此博仅仅是为了积累,纯当笔记来用。如有看官光临小生博客,请不要相信我的代码就是正确的。如果您发现了错误也恳请耽误您一点时间,请您在下面指出来,不胜感激!

如果发现一些笔记的说法完全是错误的请建议我删除!

如下代码介绍sigprocmask,sigsuspend,sigpending用法,有点糊涂先记着

每个进程都有一个用来描述哪些信号递送到进程时将被阻塞的信号集,该信号集中的所有信号在递送到进程后都将被阻塞。下面是与信号阻塞相关的几个函数:

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

sigprocmask()函数能够根据参数how来实现对信号集的操作,操作主要有三种:

参数how 进程当前信号集
SIG_BLOCK 在进程当前阻塞信号集中添加set指向信号集中的信号
SIG_UNBLOCK 如果进程阻塞信号集中包含set指向信号集中的信号,则解除对该信号的阻塞
SIG_SETMASK 更新进程阻塞信号集为set指向的信号集

sigpending(sigset_t *set))获得当前已递送到进程,却被阻塞的所有信号,在set指向的信号集中返回结果。

sigsuspend(const sigset_t *mask))用于在接收到某个信号之前, 临时用mask替换进程的信号掩码, 并暂停进程执行,直到收到信号为止。sigsuspend 返回后将恢复调用之前的信号掩码。信号处理函数完成后,进程将继续执行。该系统调用始终返回-1,并将errno设置为EINTR。

#include<stdio.h>
#include<stdlib.h>
#include<signal.h>
#include<unistd.h>void handle(int s)
{printf("handling signal^^^^\n");sleep(2);printf("handling signal over\n");
}void handle1(int s)
{printf("handling SIGUSR1\n");sleep(2);printf("handling SIGUSR1 over\n");
}void handle2(int s)
{printf("handling SIGUSR2\n");sleep(2);printf("handling SIGUSR2 over\n");
}int main()
{printf("%d\n",getpid());sigset_t sigs,sigt,sigu;sigemptyset(&sigs);sigemptyset(&sigt);sigemptyset(&sigu);sigaddset(&sigs,SIGINT);sigaddset(&sigs,SIGUSR2);sigaddset(&sigt,SIGUSR1);signal(SIGINT,handle);signal(SIGUSR1,handle1);signal(SIGUSR2,handle2);sigprocmask(SIG_BLOCK,&sigs,0);for(int i = 0;i < 10;i++){printf("breaking %d wall\n",i);sleep(5);printf("breaking%d wall over\n",i);sigsuspend(&sigt);}printf("all is over\n");sigprocmask(SIG_UNBLOCK,&sigs,0);return 0;
}</span></span>

与上一段代码对比着分析SIGUSR1这个信号的被处理方式。

<span style="font-size:18px;"><span style="font-size:18px;">#include<stdio.h>
#include<stdlib.h>
#include<signal.h>
#include<unistd.h>void handle(int s)
{printf("handling signal^^^^\n");sleep(2);printf("handling signal over\n");
}void handle1(int s)
{printf("handling SIGUSR1\n");sleep(2);printf("handling SIGUSR1 over\n");
}void handle2(int s)
{printf("handling SIGUSR2\n");sleep(2);printf("handling SIGUSR2 over\n");
}int main()
{printf("%d\n",getpid());sigset_t sigs,sigt,sigu;sigemptyset(&sigs);sigemptyset(&sigt);sigemptyset(&sigu);sigaddset(&sigs,SIGINT);sigaddset(&sigs,SIGUSR2);sigaddset(&sigt,SIGUSR1);signal(SIGINT,handle);signal(SIGUSR1,handle1);signal(SIGUSR2,handle2);sigprocmask(SIG_BLOCK,&sigs,0);for(int i = 0;i < 20;i++){printf("breaking %d wall\n",i);sleep(5);printf("breaking%d wall over\n",i);sigpending(&sigu);if(sigismember(&sigu,SIGINT) || sigismember(&sigu,SIGUSR2)||sigismember(&sigu,SIGUSR1)){sigsuspend(&sigt);}}printf("all is over\n");sigprocmask(SIG_UNBLOCK,&sigs,0);return 0;
}
</span></span>

sigsuspend使原来被屏蔽信号恢复,使suspend第一个参数中的集合中的信号被屏蔽(第二段代码好像违背这一说法),当某个信号处理函数处理完毕后,sigsuspend重新屏蔽被他恢复的信号之后返回。

在信号处理函数被调用的时候,可能会有信号干扰正在被调用的信号处理函数(信号处理函数默认的屏蔽正在处理的信号

sigaction与signal的作用类似,sigqueue与kill作用类似用于发送信号

sigaction绑定的信号处理函数有保护层,当信号处理函数被调用时可以屏蔽指定的信号;sigqueue可以在发送信号的时候发送数据过去。

以下代码说明sigaction的用法

<span style="font-size:18px;">#include<stdio.h>
#include<signal.h>
#include<unistd.h>void handle(int s)
{printf("OOOOK\n");sleep(5);printf("KOOOO\n");
}int main()
{printf("%d\n",getpid());struct sigaction act = { 0 };act.sa_handler = handle;sigemptyset(&act.sa_mask);sigaddset(&act.sa_mask,SIGINT);act.sa_flags = SA_SIGINFO;sigaction(SIGUSR1,&act,0);while(1);return 0;
} </span>

通过以下代码可以对上面进程发送信号相当于kill

#include<stdio.h>
#include<signal.h>
#include<unistd.h>int main()
{union sigval val;sigqueue(2222,SIGUSR1,val);return 0;
}

sigaction的另一种使用方法,在发送信号的同时可以发送数据(数据包括整型数据和指针型数据,在多个进程间发数据时指针数据可能不是我们想要的)

#include<stdio.h>
#include<signal.h>
#include<unistd.h>void handle_1(int s,siginfo_t* info,void *d)
{printf("OOOOK:%d\n",info->si_int);sleep(5);printf("KOOOO\n");
}int main()
{printf("%d\n",getpid());struct sigaction act = { 0 };//act.sa_handler = handle;act.sa_sigaction = handle_1;sigemptyset(&act.sa_mask);sigaddset(&act.sa_mask,SIGINT);act.sa_flags = SA_SIGINFO;sigaction(SIGUSR1,&act,0);while(1);return 0;
}

这里的sigaction能在信号处理函数进行的时候屏蔽信号的功能来自于sigaction函数的第二个参数

以下代码通过sigqueue函数给以上进程发送信号和数据

#include<stdio.h>
#include<signal.h>
#include<unistd.h>int main()
{union sigval val;val.sival_int = 66;sigqueue(2495,SIGUSR1,val);return 0;
}

Linux信号控制-sigprocmask,sigsuspend,sigpending,sigaction,sigqueue相关推荐

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

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

  2. Linux信号、进程间关系pause, 时序竞态,sigsuspend

    1. pause函数 --> wait for signal 该函数可以造成进程主动挂起,等待信号唤醒.调用该系统调用的进程将处于阻塞状态(主动放弃CPU)直到有信号递达将其唤醒. int pa ...

  3. Linux 信号signal\sigaction

    转发:作者,故事狗 https://www.jianshu.com/p/f445bfeea40a Linux 信号signal 对于 Linux来说,实际信号是软中断,许多重要的程序都需要处理信号.信 ...

  4. 【B站视频笔记】linux 进程间通信(ipc)信号(软中断信号)signal库函数、可靠信号和不可靠信号、信号集sigprocmask(信号掩码、信号递达Delivery、信号未决Pending)

    [视频教程]Linux信号详解(可靠信号.不可靠信号.阻塞信号.信号处理函数) [博文]Linux信号 文章目录 背景 课程笔记 一.如何让程序在后台运行 1.加"&"符号 ...

  5. linux_信号_sigemptyset函数-sigfillset函数-sigaddset函数-sigdelset函数-sigismember函数-sigprocmask函数-sigpending函数

    接上一篇:linux_设置定时器(C语言)-alarm函数-time命令-settimer函数   昨天介绍了通过alarm函数和setitimer函数产生信号,今天继续介绍信号的新知识--信号集的操 ...

  6. Linux信号详解:signal与sigaction函数【2】

    我们已经讨论了Linux操作系统中"信号"."中断"."僵尸进程"'等重要概念.结合C语言中的setjmp.longjump.sigsetj ...

  7. Linux信号sigaction / signal

    Linux信号sigaction / signal 文章目录 Linux信号sigaction / signal 目的 函数原型 struct sigaction 信号枚举值 ISO C99 sign ...

  8. linux信号之sigsuspend和setitimer

    函数原型:sigsuspend(const sigset_t *mask) 作用:用于在接收到某个信号之前, 临时用mask替换进程的信号掩码, 并暂停进程执行,直到收到信号为止. sigsuspen ...

  9. Linux学习笔记22——sigsuspend 让指定的信号无法唤醒进程

    1,由来 让指定的信号无法唤醒进程貌似很简单,只要先设置屏蔽字屏蔽指定的信号,再pause就可以了.以后只要接收到信号,切该信号不是指定的信号就可以结束 pause.但是,这种做法是分两步做的,而信号 ...

最新文章

  1. PHP命名空间学习笔记
  2. 应急指南|新一轮勒索病毒来袭,小白用户看这里
  3. GitHub 新手教程 四,Git GUI 新手教程(1),OpenSSH Public Key
  4. 用matlab求三重积分格式,matlab求三重积分
  5. johnson算法c语言,Johnson-Trotter(JT)算法生成排列
  6. 测井曲线wis文件格式转换为ASCII文本格式小软件的开发(C与Python结合开发)
  7. dhtml gantt所有配置_dhtmlxGantt
  8. matlab 粒子群应用,粒子群算法程序应用
  9. 大前研一:聪明人必作的十件事
  10. python爬取每日腾讯新闻数据
  11. [Java] 编码规范与基本概念
  12. 人艰不拆~找实习之路(二)。
  13. swift和swiftui_在swiftui中查看布局和演示
  14. 如何零成本实现微信公众号自助查券返利机器人(二)
  15. 使用 Python3 获取网页源代码
  16. css弹性盒之justify-content详解
  17. 利用jmap查看一个class声称的实例个数
  18. 不要打梦到的电话号码。。。
  19. 腾讯x5内核使用方法全网最简单手动安装安卓APP
  20. 开票系统导出的OFD文档如何转换PDF格式?

热门文章

  1. 数据基础设施白皮书2019
  2. @media媒体查询
  3. 打破传统电商格局,新型社交电商到底有什么优点?
  4. 电脑图片无损放大怎么操作?怎么无损放大图片?
  5. Vue为数字添加逗号分隔
  6. comsol移动网格_comsol网格设置技巧,网格
  7. 王坚:阿里巴巴为什么会“去IOE”(一) | 《商业价值》杂志
  8. java基础英语词汇
  9. CSS实现水平局中、垂直局中详解
  10. python3打印99乘法表