sigprocmask , sigpending 和 sigsuspend函数
转自 http://blog.csdn.net/elbort/article/details/7594772
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(); //
return ;
}
结果显示:
[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) == )
{
printf("SIGINT was came.\n");
}
if(sigismember(&pset,SIGQUIT) == )
{
printf("SIGQUIT was came.\n");
}
if(sigismember(&pset,SIGABRT) == )
{
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]$
注意:红色那句去掉//会得到完全不同的结果。为什么??
//测试后,发现真的是
SIGINT was came.
SIGQUIT was came.
SIGABRT was came. 这三句话没有打印出来,不太好理解啊,sigprocmask( SIG_UNBLOCK, &set, &oset );这句话是解除进程的信号屏蔽set,此时阻塞的SIGINT,SIGQUIT,SIGABRT信号在sigprocmask返回之前被投递到进程,没有未决的信号了。
sigsuspend函数
功能:它有一套属于自己的屏蔽信号mask,能够选择性接收某些信号。在接收到可行信号(也即是没有被屏蔽的信号)之前,运行到它时,它会一直挂起,有点类似pause()函数。接受到可行信号后,或者中断进程的信号,它会退出挂起并执行相应的信号函数。接收到的信号源:1.之前运行sigprocmask()函数中阻塞的信号;2.挂起后接受到的信号。
代码说明: Example:sigsuspend (Correct Way to Wait for Single Signal)
sigset_t maskall, 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();
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();
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();
printf("\nTest finish\n");
return ;
}
结果显示:
[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]$
sigprocmask , sigpending 和 sigsuspend函数的更多相关文章
- sigprocmask, sigpending, sigsuspend的用法
sigset_t set sigemptyset(&set) :清空阻塞信号集合变量 sigfillset(&set) :添加所有的信号到阻塞集合变量里 sigaddset(& ...
- ZT sigprocmask,sigpending函数
sigprocmask,sigpending函数 分类: LINUX 2012-02-02 16:39 905人阅读 评论(0) 收藏 举报 signalredhatnulllinux [sigpro ...
- 【C】——利用sigsuspend函数等待信号阻塞进程
#include<signal.h> int sigsuspend(const sigset_t *sigmask); 返回值:-,并将errno设置为EINTR 将进程的信号屏蔽字设置为 ...
- 信号之sigsuspend函数
更改进程的信号屏蔽字可以阻塞所选择的信号,或解除对它们的阻塞.使用这种技术可以保护不希望由信号中断的代码临界区.如果希望对一个信号解除阻塞,然后pause等待以前被阻塞的信号发生,则又将如何呢?假定信 ...
- UNIX环境高级编程——sigqueue、sigsuspend函数
一.sigqueue函数 功能:新的发送信号系统调用,主要是针对实时信号提出的支持信号带有参数,与函数sigaction()配合使用. int sigqueue(pid_t pid, int sig, ...
- 竞态条件与sigsuspend函数
一.利用pause和alarm函数实现sleep函数 #include <unistd.h> int pause(void); pause函数使调用进程挂起直到有信号递达.如果信号的处理动 ...
- Linux进程间通信(二):信号集函数 sigemptyset()、sigprocmask()、sigpending()、sigsuspend()
我们已经知道,我们可以通过信号来终止进程,也可以通过信号来在进程间进行通信,程序也可以通过指定信号的关联处理函数来改变信号的默认处理方式,也可以屏蔽某些信号,使其不能传递给进程.那么我们应该如何设定我 ...
- sigsuspend sigprocmask函数的用法
一个进程的信号屏蔽字规定了当前堵塞而不能递送给该进程的信号集.调用函数sigprocmask能够检測或更改其信号屏蔽字,或者在一个步骤中同一时候运行这两个操作. #include <signal ...
- 信号屏蔽的切换的理解sigsuspend
#include <stdio.h> #include <stdlib.h> #include <signal.h> #include <unistd.h&g ...
随机推荐
- Crossword Expert CodeForces - 1194F (期望)
大意: $n$个题, 按照第$i$题随机$t_i$或$t_i+1$秒钟完成, 最多做$T$秒, 求做题数期望. 期望转为做题数$\ge x$的方案数之和最后再除以总方案数 这是因为$\sum\limi ...
- 【转】Visual Studio Code必备插件
先ctrl+shift+p,弹出命令面板-选中Extensions:Install Extensions 或者直接点击左侧栏这个扩展按钮(Ctrl+Shift+X) 然后左侧栏就会显示出很多插件,如图 ...
- Manacher算法+注释
Manacher算法是用来求一个字符串中最长回文串的算法. 考虑暴力求最长回文串的做法: 暴力枚举字符串中的所有字串判断是否回文,然后求最大值. 时间复杂度O(n^3),考虑优化. 我们从枚举所有字串 ...
- (错误) Eclipse使用Maven创建Web时错误
转自:http://blog.csdn.net/afgasdg/article/details/12757433 问题描述: 使用Eclipse自带的Maven插件创建Web项目时报错: Could ...
- JDBC 复习1 DBUtil
package dbex; import java.io.Closeable; import java.io.IOException; import java.io.InputStream; impo ...
- Android开发之图像处理那点事——滤镜
在Android开发中,一般对图像的处理就是Bitmap(位图),它包含了图像的全部数据,即点阵和颜色值,点阵就是包含像素点的矩阵,而颜色值就是ARGB,分别代表透明.红色.绿色.蓝色通道,它们共同决 ...
- 免安装方式的Python之VSCode环境配置
概述 本文旨在介绍免安装方式,在VSCode中搭建Python(3.73)的配置环境.至于Python是什么.它能做些什么,诸如此类的介绍均不在此文中介绍,相信能看此文的人,多多少少都会有些了解. V ...
- 【Hibernate】 二级缓存及查询缓存
一.Hibernate的二级缓存 1.1 类缓存区特点 缓存的是对象的散装的数据. 图一 Hibernate的二级缓存的散装数据 1.2 集合缓存区的特点: 缓存的是对象的id.需要依赖类缓冲区的配置 ...
- Image Processing and Analysis_8_Edge Detection:Local Scale Control for Edge Detection and Blur Estimation——1998
此主要讨论图像处理与分析.虽然计算机视觉部分的有些内容比如特 征提取等也可以归结到图像分析中来,但鉴于它们与计算机视觉的紧密联系,以 及它们的出处,没有把它们纳入到图像处理与分析中来.同样,这里面也有 ...
- Java基础 使用转换流进行文件的复制 / RandomAccessFile 类进行文件的复制
笔记: **使用转换流进行文件的复制 文本文件---字节流FileInputStream--> [InputStreamReader] -----字符流BufferedReader------ ...